2011-07-18 212 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我编辑了答案 - 一个视图绑定似乎也起作用。 –