为什么iWantInt(a)
在iWantInt(b)
时无法编译而且 - 更令人惊讶的是iWantInt
呢?
我如何理解这种行为?
为什么我无法明确地将a
传递给iWantInt
?
iWantA
与iWantInt
的区别如何?为什么它的工作方式不一样?
是否在某处记录/解释了这种行为?
如果Scala接受iWantInt(a)
会导致什么样的问题?为什么禁止它?
class A
class B
object Run extends App {
implicit val a = new A
implicit val b = new B
implicit def A2Int(implicit a:A)=1
implicit def B2Int(b:B)=2
def iWantA(implicit a:A)=println("A")
def iWantInt(implicit i: Int) = println(i)
iWantInt(b) // prints 2
iWantInt // prints 1
// iWantInt(a) // when uncommented this line does not compile, why ?
iWantA // prints A
iWantA(a) // prints A
}
答案 0 :(得分:4)
A2Int
不是定义隐式转换,而是表示已声明为隐式的值,例如示例中的implicit val a
,唯一的区别是必须发现隐式A
在它的工作范围内。这是允许iWantInt
没有显式参数进行编译的内容 - 编译器将A2Int
视为隐式Int
,然后找到a
作为A
的隐式A2Int
{1}}。
对于有资格作为隐式转换的函数,它必须采用单个非隐式参数。 B2Int
采用单个参数(b: B)
,因此符合要求。这允许iWantInt(b)
编译。 A2Int
有(implicit a: A)
,但由于此参数是隐式A2Int
不符合要求,因此iWantInt(a)
无法编译,除非添加了implicit def A2Int2(a:A) = 1
之类的行。如果您使用scalac
标记运行-feature
(它至少建议使用2.11),它会显示B2Int
和A2Int2
的警告,说隐式转换应该是明确的通过显示scala.language.implicitConversions
来启用。它没有显示A2Int
的警告,表明编译器不会将其视为隐式转换。
Scala Language Reference是Scala的最终定义。有关这些特定功能的行为规范,请参见第7章“隐式参数和视图”。