为什么隐式参数在进行隐式转换时无法显式传递?

时间:2014-03-31 21:31:14

标签: scala implicit-conversion implicit

为什么iWantInt(a)iWantInt(b)时无法编译而且 - 更令人惊讶的是iWantInt呢?

我如何理解这种行为?

为什么我无法明确地将a传递给iWantInt

iWantAiWantInt的区别如何?为什么它的工作方式不一样?

是否在某处记录/解释了这种行为?

如果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
}

1 个答案:

答案 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),它会显示B2IntA2Int2的警告,说隐式转换应该是明确的通过显示scala.language.implicitConversions来启用。它没有显示A2Int的警告,表明编译器不会将其视为隐式转换。

Scala Language Reference是Scala的最终定义。有关这些特定功能的行为规范,请参见第7章“隐式参数和视图”。