2011-07-18 37 views
8

Tôi muốn một bộ giải nén để chuyển đổi hoàn toàn các tham số của nó, nhưng nó dường như không hoạt động. Hãy xem xét trường hợp này rất đơn giản:Scala - chuyển đổi ngầm với unapply

case class MyString(s: String) {} 

implicit def string2mystring(x: String): MyString = new MyString(x) 
implicit def mystring2string(x: MyString) = x.s 

object Apply { 
    def unapply(s: MyString): Option[String] = Some(s) 
} 

Nhưng tôi không thể sử dụng nó như tôi mong chờ:

val Apply(z) = "a" // error: scrutinee is incompatible with pattern type 

bất cứ ai có thể giải thích lý do tại sao nó không thành công để chuyển đổi các tham số String-MyString? Tôi hy vọng nó sẽ gọi số string2mystring("a") khi đang bay. Rõ ràng tôi có thể giải quyết vấn đề bằng cách nói val Apply(y) = MyString("a"), nhưng có vẻ như tôi không phải làm như vậy.

Lưu ý: Câu hỏi này tương tự như this one, nhưng 1) câu hỏi đó không thực sự có câu trả lời hay về lý do tại sao điều này xảy ra, 2) ví dụ phức tạp hơn cần thiết.

Trả lời

14

Chuyển đổi ngầm định không được áp dụng khi đối sánh mẫu. Đó không phải là một lỗi hoặc một vấn đề với mã của bạn, nó chỉ đơn giản là một quyết định thiết kế của những người sáng tạo của Scala.

Để khắc phục sự cố, bạn nên viết trình giải nén khác chấp nhận số String - do đó có thể gọi chuyển đổi ngầm của bạn.

Ngoài ra, bạn có thể thử với một cái nhìn bị ràng buộc, mà dường như làm việc tốt, và cũng sẽ làm việc nếu sau đó bạn xác định chuyển đổi tiềm ẩn khác để MyString:

object Apply { 
    def unapply[S <% MyString](s: S): Option[String] = Some(s.s) 
} 
+1

Cảm ơn. Đó là một chút thất vọng. Bạn có biết động lực là gì cho quyết định đó không? – dhg

+0

Yep, thêm 'def unapply (p: String): Option [String] = Một số (p)' thành 'Áp dụng' thực hiện thủ thuật. Vì vậy, tôi sẽ đi với điều đó. Cảm ơn. – dhg

+0

@dhg Tôi đã chỉnh sửa câu trả lời - một chế độ xem bị ràng buộc dường như hoạt động tốt. –

Các vấn đề liên quan