为什么显式调用Scala方法允许隐式解析它? [英] Why does this explicit call of a Scala method allow it to be implicitly resolved?

查看:97
本文介绍了为什么显式调用Scala方法允许隐式解析它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why does this code fail to compile, but compiles successfully when I uncomment the indicated line? (I'm using Scala 2.8 nightly). It seems that explicitly calling string2Wrapper allows it to be used implicitly from that point on.

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) {}
    }
  }
}

编辑:感谢您到目前为止的回答,其中包括指向马丁·奥德斯基评论的指针,

Edit: thanks for the answers so far, which include a pointer to Martin Odersky's comment,

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

"An implicit conversion without explicit result type is visible only in the text following its own definition. That way, we avoid the cyclic reference errors."

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

I'd still be interested in finding out 1) what is the danger of "cyclic reference errors"?, and 2) Why does an explicit call make any difference?

推荐答案

明确指定string2Wrapper的返回类型可解决此问题.

Explicitly ascribing the return type of string2Wrapper fixes the problem.

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) {}
    }
  }
}

bar之前定义Implicits也可以:

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"
  } 
}

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

If you need to rely on a implicit conversion defined below within the current scope, make sure you annotate its return type. Pretty sure this has come up on the mailing lists before, and may be expected behaviour rather than a bug. But I can't locate it at the moment. I guess the explicit call in foo triggers the type inference of the return type of bar, which is then valid when typing the contents of bar.

更新

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

What is the danger of the cyclic reference error?

隐式方法的主体可以调用需要隐式转换的方法.如果两者都具有推断的返回类型,那么您将陷入僵局.这不适用于您的示例,但是编译器不会尝试检测到这一点.

The body of the implicit method may call the method that requires the implicit conversion. If both of these have an inferred return type, you're at an impasse. This doesn't apply in your example, but the compiler doesn't attempt to detect this.

为什么显式调用会有所作为?

Why does an explicit call make a difference?

早期的显式调用触发隐式方法的返回类型的类型推断.这是Implicits.isValid

The explicit call earlier triggers type inference of the return type of the implicit method. Here's the logic in Implicits.isValid

sym.isInitialized ||
      sym.sourceFile == null ||
      (sym.sourceFile ne context.unit.source.file) || 
      hasExplicitResultType(sym) ||
      comesBefore(sym, context.owner)

更新2

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

This recent bug looks relevant: https://lampsvn.epfl.ch/trac/scala/ticket/3373

这篇关于为什么显式调用Scala方法允许隐式解析它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆