Scala - 隐式转换与 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)
}
但我无法按预期使用它:
val Apply(z) = "a" // error: scrutinee is incompatible with pattern type
任何人都可以解释为什么它无法将参数从 String
转换为 MyString
吗?我希望它能够即时调用 string2mystring("a")
。显然,我可以通过说 val Apply(y) = MyString("a")
来解决这个问题,但似乎我不应该这样做。
注意:这个问题类似于这个一个,但是 1)对于为什么会发生这种情况并没有一个很好的答案,2)这个例子比它需要的更复杂。
I'd like an extractor to implicitly convert its parameters, but it doesn't seem to work. Consider this very simple case:
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)
}
But I'm not able to use it as I would expect:
val Apply(z) = "a" // error: scrutinee is incompatible with pattern type
Can anyone explain why it fails to convert the parameter from String
to MyString
? I would expect it to call string2mystring("a")
on the fly. Clearly I could work around the issue by saying val Apply(y) = MyString("a")
, but it doesn't seem like I should have to do that.
Note: This question is similar to this one, but 1) that one doesn't really have a good answer for why this is happening, 2) the example is more complex than it needs to be.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
模式匹配时不应用隐式转换。这不是代码的错误或问题,这只是 Scala 创建者的设计决策。
要修复它,您应该编写另一个接受
String
的提取器 - 它反过来可以调用您的隐式转换。或者,您可以尝试使用视图绑定,这似乎也有效,并且如果您稍后定义其他到
MyString
的隐式转换,它也将有效:Implicit conversions are not applied when pattern matching. That's not a bug or a problem with your code, it's simply a design decision of the creators of Scala.
To fix it, you should write another extractor that accepts a
String
— which in turn can call your implicit conversion.Alternatively, you can try with a view bound, which seems to work as well, and will also work if you later define other implicit conversions to
MyString
: