【问题标题】:Why implicit parameters cannot be passed explicitly when they undergo an implicit conversion?为什么隐式参数在进行隐式转换时不能显式传递?
【发布时间】:2014-03-31 21:31:13
【问题描述】:

为什么iWantInt(a) 无法编译,而iWantInt(b) - 更令人惊讶的是 - iWantInt 可以编译?

我如何理解这种行为?

当我可以隐式传递时,为什么我不能显式传递aiWantInt

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
}

【问题讨论】:

    标签: scala implicit-conversion implicit


    【解决方案1】:

    A2Int 不是定义隐式转换,而是像一个已声明为隐式的值,如示例中的 implicit val a,唯一的区别是必须在范围内发现隐式 A 才能工作.这就是允许在没有显式参数的情况下编译 iWantInt 的原因 - 编译器发现 A2Int 作为隐含的 Int,然后发现 a 作为隐含的 A for A2Int

    要使函数符合隐式转换的条件,它必须采用单个非隐式参数。 B2Int 采用单个参数(b: B),因此满足要求。这允许iWantInt(b) 编译。 A2Int(implicit a: A) 但是因为这个参数是隐式的 A2Int 不符合要求,所以 iWantInt(a) 不会编译,除非添加像 implicit def A2Int2(a:A) = 1 这样的行。如果您使用-feature 标志运行scalac(至少在2.11 中会建议),它将显示B2IntA2Int2 的警告,表示应通过使scala.language.implicitConversions 可见来显式启用隐式转换。它没有显示A2Int 的警告,表明编译器没有将其视为隐式转换。

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

    【讨论】:

    • 感谢您的回答!您能否澄清一下“隐式转换需要有一个非隐式参数”是什么意思。 ?隐式参数 where ?
    • 所以你的意思是隐式 def A2Int(implicit a:A) 不能算作隐式转换,因为它的参数是隐式的?
    • 是的,没错。我已经编辑了第二段以使其更清晰。
    • 非常感谢!我认为是时候尝试真正了解 SLS。
    猜你喜欢
    • 2014-04-28
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多