让我们考虑一下这段代码:
class A
object A{
implicit def A2Int(implicit a:A)=1
implicit def A2String(a:A)="Hello"
}
object Run extends App{
implicit val a: A =new A
import A.A2Int
// without this import this code does not compile, why ?
// why is no import needed for A2String then ?
def iWantInt(implicit i:Int)=println(i)
def iWantString(implicit s:String)=println(s)
iWantInt
iWantString(a)
}
它运行并打印:
1
Hello
现在,如果我们将该行注释掉
import A.A2Int
然后我们得到一个编译错误:
如果该行被注释掉了,为什么Scala找不到A.A2String
会找不到A.A2Int
?
如何解决这个问题?
感谢阅读。
答案 0 :(得分:3)
不同之处在于,当您执行iWantString(a)
时,编译器将获得一些起点:您正在显式传递a
,编译器知道该类型为A
。
鉴于iWantString
需要String
而非A
,编译器将搜索从A
到String
的隐式转换,以便插入并生成A
通话成功。
隐式查找规则声明编译器必须在类A
的伴随对象中查找(以及其他位置),因为类型A2String
是转换的源类型。
这是它找到隐式转换A
的地方。
你必须得到的是,只是因为你传递了A
的一个实例,编译器才知道要查找隐式转换到iWantInt
的伴随对象。
当您执行A
时,编译器没有理由查看A2Int
,因此它不会找到您的方法Int
(并且范围内没有其他方法/值)提供类型{{1}}的隐式值,然后编译失败)。
有关隐式查找规则的详细信息,请参阅 请参阅http://www.scala-lang.org/docu/files/ScalaReference.pdf(第7.2章)中的scala规范。这是最相关的摘录:
类型T的隐式范围由类的所有伴随模块(第5.4节)组成 与隐式参数的类型相关联的。