2010-12-13 23 views
5

có gì sai trong đoạn mã này?scala hoặc pattern match

(Left("aoeu")) match{case Right(x) => ; case Left(x) => }
<console>:6: error: constructor cannot be instantiated to expected type; 
found : Right[A,B] 
required: Left[java.lang.String,Nothing]  

tại sao mô hình khớp chỉ không bỏ qua phải và kiểm tra lại?

+0

Um, trình biên dịch cho bạn biết rằng một số mã của bạn không thể truy cập được. Đó là một điều tốt, phải không? –

Trả lời

11

Nhập ngầm định suy ra rằng Left("aoeu")Left[String,Nothing]. Bạn cần phải gõ nó một cách rõ ràng.

(Left("aoeu"): Either[String,String]) match{case Right(x) => ; case Left(x) => } 

Có vẻ như mẫu ứng cử viên khớp phải luôn là loại phù hợp với giá trị được khớp.

scala> case class X(a: String) 
defined class X 

scala> case class Y(a: String) 
defined class Y 

scala> X("hi") match { 
    | case Y("hi") => ; 
    | case X("hi") => ; 
    | } 
<console>:11: error: constructor cannot be instantiated to expected type; 
found : Y 
required: X 
     case Y("hi") => ; 
      ^

Tại sao nó hoạt động như thế này? Tôi nghi ngờ không có lý do chính đáng để cố gắng khớp với loại không tương thích. Cố gắng làm như vậy là một dấu hiệu cho thấy các nhà phát triển không viết những gì họ thực sự có ý định. Lỗi trình biên dịch giúp ngăn ngừa lỗi.

+4

Tôi nghĩ bạn đã nhấn mạnh điểm mấu chốt: trình biên dịch đã chỉ ra chính xác rằng một phần của mã không thể truy cập được. Có, bạn có thể đánh bại lỗi đó, nhưng bạn không nên. – Malvolio

3
scala> val left: Either[String, String] = Left("foo") 
left: Either[String,String] = Left(foo) 

scala> left match { 
    | case Right(x) => "right " + x 
    | case Left(x) => "left " + x } 
res3: java.lang.String = left foo