[英]Scala implicit implicit
我试图在我的代码中做一些隐含的魔法,但问题很简单,我已经把它提取出来了。 这似乎有点奇怪,因为从我读过的内容来看,以下内容应该有效。
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
s 定义的,而不是String
s。 但我确实告诉过你如何将 go 从String
s 转换为Double
s,并且这里没有歧义(据我所知),所以你不应该注意到"2.0".twice
可以通过做strToDouble("2.0").twice
?
我在这里错过了什么吗? 或者这是一种优化,以便编译器不会尝试所有可能的implicits
排列(这将以超指数方式增长,我认为是阶乘)。 我想我真的在寻找对此的确认或拒绝。
谢谢
如果您希望扩展方法即使在隐式转换后也适用,您可以修复隐式 class 的定义
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
s 定义的,而不是String
s。 但我确实告诉过你如何将 go 从String
s 转换为Double
s,并且这里没有歧义(据我所知),所以你不应该注意到"2.0".twice
可以通过做strToDouble("2.0").twice
?
根据规范,隐式转换仅适用于三种情况
为什么编译器 select 在使用 lambda 速记时不能使用正确的 String.contains 方法?
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
到C
的转换
case class A(i: Int)
case class B(i: Int)
case class C(i: Int)
implicit def aToB(a: A): B = B(a.i)
implicit def bToC(b: B): C = C(b.i)
A(1): B // compiles
B(1): C // compiles
// A(1): C //doesn't compile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.