为什么Scala方法的显式调用允许隐式解析?

Mat*_*t R 16 scala implicit scala-2.8

为什么此代码无法编译,但在取消注释指示的行时成功编译?(我每晚都使用Scala 2.8).似乎显式调用string2Wrapper允许从该点隐式使用它.

class A {
  import Implicits.string2Wrapper
  def foo() {
     //string2Wrapper("A") ==> "B" // <-- uncomment
  } 
  def bar() {
    "A" ==> "B"
    "B" ==> "C"
    "C" ==> "D"
  }
  object Implicits {
    implicit def string2Wrapper(s: String) = new Wrapper(s)
    class Wrapper(s: String) {
      def ==>(s2: String) {}
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:感谢目前为止的答案,其中包括指向Martin Odersky评论的指针,

"没有显式结果类型的隐式转换只能在自己定义的文本中可见.这样,我们就避免了循环引用错误."

我仍然有兴趣找出1)"循环参考错误"的危险是什么?,2)为什么显式调用有什么不同?

ret*_*nym 21

明确归因于string2Wrapper的返回类型可以解决问题.

class A {
  import Implicits._

  def bar() {    
    "A" ==> "B"
    "B" ==> "C"
    "C" ==> "D"
  }
  object Implicits {
    implicit def string2Wrapper(s: String): Wrapper = new Wrapper(s)
    class Wrapper(s: String) {
      def ==>(s2: String) {}
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

定义Implicits之前bar也有效:

class A {
  object Implicits {
    implicit def string2Wrapper(s: String) = new Wrapper(s)
    class Wrapper(s: String) {
      def ==>(s2: String) {}
    }
  }

  import Implicits._

  def bar() {    
    "A" ==> "B"
    "B" ==> "C"
    "C" ==> "D"
  } 
}
Run Code Online (Sandbox Code Playgroud)

如果您需要依赖当前范围内的下面定义的隐式转换,请确保注释其返回类型.很确定之前已经出现在邮件列表上,可能是预期的行为而不是错误.但我现在无法找到它.我猜显式调用foo会触发返回类型的类型推断,bar然后在键入内容时有效bar.

UPDATE

循环参考错误有什么危险?

隐式方法的主体可以调用需要隐式转换的方法.如果这两个都具有推断的返回类型,那么你就陷入了僵局.这不适用于您的示例,但编译器不会尝试检测此情况.

为什么显式通话会产生影响?

先前的显式调用触发隐式方法的返回类型的类型推断.这是逻辑Implicits.isValid

sym.isInitialized ||
      sym.sourceFile == null ||
      (sym.sourceFile ne context.unit.source.file) || 
      hasExplicitResultType(sym) ||
      comesBefore(sym, context.owner)
Run Code Online (Sandbox Code Playgroud)

更新2

这个最近的错误看起来很相关:https://lampsvn.epfl.ch/trac/scala/ticket/3373


psp*_*psp 12

如果你晚上只是在ooooone,你会看到我昨天添加的错误消息.

<console>:11: error: value ==> is not a member of java.lang.String
 Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
           "A" ==> "B"
           ^
<console>:12: error: value ==> is not a member of java.lang.String
 Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
           "B" ==> "C"
           ^
<console>:13: error: value ==> is not a member of java.lang.String
 Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
           "C" ==> "D"
           ^
Run Code Online (Sandbox Code Playgroud)