如何解决Scala隐式隐式
我正在尝试在代码中做一些隐式魔术,但是问题非常简单,我在这里已将其提取出来。从我阅读的内容来看,以下内容应该可以工作,这似乎有点奇怪。
implicit class Foo(value: Double) {
def twice = 2*value
}
2.0.twice
implicit def strToDouble(x: String) = Try(x.toDouble) match {
case Success(d) => d
case Failure(_) => 0.0
}
strToDouble("2.0").twice
val a: Double = "2.0"
val b: Double = "equals 0.0"
"2.0".twice
我收到一个编译错误
value twice is not a member of String
[error] "2.0".twice
我为您提供了编译器,为Double
(而非String
)定义了两次。但是我确实告诉过您如何从String
到Double
s,而且这里没有歧义(据我所知),所以您不应该注意到{{ 1}}可以通过"2.0".twice
完成吗?
我在这里想念什么吗?还是这是一种优化,以便编译器不会尝试strToDouble("2.0").twice
的所有可能排列(我认为它会成指数增长)。我想我实际上是在寻求确认或拒绝。
谢谢
解决方法
如果希望扩展方法即使在隐式转换后仍然适用,则可以修复隐式类的定义
implicit class Foo[A](value: A)(implicit ev: A => Double) {
def twice: Double = 2 * value
}
implicit def strToDouble(x: String): Double = ???
2.0.twice //compiles
"2.0".twice //compiles
我为您提供了编译器,
twice
是为Double
而不是String
定义的。但是我 确实告诉您如何从String
到Double
s,而且没有 据我所知,这里的模棱两可,所以你不应该 请注意,"2.0".twice
可以通过strToDouble("2.0").twice
完成吗?
根据规范,隐式转换仅在三种情况下适用
Why can't the compiler select the correct String.contains method when using this lambda shorthand?
https://scala-lang.org/files/archive/spec/2.13/07-implicits.html#views
从2.0.twice
到Foo(2.0).twice
的转换是第二种情况,而从"2.0"
到strToDouble("2.0")
的转换是第一种情况。如您所见,没有项目可以将它们一起应用。因此,如果您希望它们一起适用,则应像我上面显示的那样明确指定。
类似地,如果您定义了从A
到B
以及从B
到C
的转化,这并不意味着您已经从A
到{ {1}}
C
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。