2011-07-18 211 views
8

我想要一個提取器隱式轉換其參數,但它似乎不工作。考慮這個非常簡單的例子:斯卡拉 - 隱式轉換與未應用

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) 
} 

但我不能使用它,因爲我所期望的:

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

任何人都可以解釋爲什麼它不能將參數轉換從StringMyString?我希望它在飛行中撥打string2mystring("a")。很明顯,我可以通過說val Apply(y) = MyString("a")解決這個問題,但似乎我不應該這樣做。

注意:這個問題類似於this one,但1)人們爲什麼會發生這種情況並沒有很好的答案,2)這個例子比它需要的更復雜。

回答

14

模式匹配時不應用隱式轉換。這不是代碼中的錯誤或問題,它僅僅是Scala創作者的設計決定。

要修復它,您應該編寫另一個接受String的提取器 - 這又可以調用您的隱式轉換。

或者,你可以用綁定一個觀點,這似乎工作,以及嘗試,也將工作,如果你以後定義其他隱式轉換爲MyString

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

感謝。這有點令人失望。你知道這個決定的動機是什麼嗎? – dhg

+0

是的,添加'def unapply(p:String):Option [String] =一些(p)'到'Apply'就可以做到這一點。所以我會去那。謝謝。 – dhg

+0

@dhg我編輯了答案 - 一個視圖綁定似乎也起作用。 –