繁体   English   中英

Scala隐含隐含

[英]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.twiceFoo(2.0).twice的转换是第二种情况, "2.0"strToDouble("2.0")的转换是第一种情况。 如您所见,没有项目可以将它们一起应用。 因此,如果您希望它们一起适用,您应该像我上面显示的那样明确指定。

同样,如果您定义了从AB和从BC的转换,这并不意味着您有从AC的转换

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM