Scala-使用unapply的隐式转换
我希望提取器隐式地转换其参数,但它似乎不起作用。想想这个非常简单的例子:Scala-使用unapply的隐式转换,scala,implicit-conversion,unapply,Scala,Implicit Conversion,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] =
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
有人能解释为什么它无法将参数从String
转换为MyString
?我希望它能够动态调用string2mysting(“a”)
。显然,我可以通过说valapply(y)=MyString(“a”)
来解决这个问题,但似乎我不应该这么做
注意:这个问题类似于,但是1)对于为什么会发生这种情况,我们没有一个很好的答案,2)这个例子比它需要的更复杂。模式匹配时不应用隐式转换。这不是代码中的错误或问题,只是Scala创建者的设计决策 要修复它,您应该编写另一个提取器来接受
字符串
——这反过来可以调用隐式转换
或者,您可以尝试使用视图绑定,它似乎也可以工作,并且如果以后定义其他到MyString
的隐式转换,也可以工作:
object Apply {
def unapply[S <% MyString](s: S): Option[String] = Some(s.s)
}
对象应用{
def unapply[S谢谢。这有点令人失望。你知道这个决定的动机是什么吗?是的,添加def unapply(p:String):Option[String]=Some(p)
toApply
起到了作用。因此我将继续。谢谢。@dhg我编辑了答案-视图绑定似乎也能起作用。太棒了!视图绑定是一个很好的解决方案。它不仅不需要为每种可能的类型编写额外的方法,而且还解决了我遇到的另一个问题:如果unapply
接受一个元组,那么由于类型擦除,无法使用重载技巧。但这会彻底解决此问题,并导致错误参数类型的编译时错误:def unapply[S