简体   繁体   English

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

[英]Why implicit parameters cannot be passed explicitly when they undergo an implicit conversion?

Why iWantInt(a) does not compile while iWantInt(b) and - what is more surprising - iWantInt does ? 为什么iWantInt(a)不能在iWantInt(b)编译而且 - 更令人惊讶的是 - iWantInt呢?

How can I understand this behaviour ? 我怎么能理解这种行为?

Why can I not pass explicitly a to iWantInt when I can pass it implicitly ? 为什么我不能明确地传递aiWantInt时,我可以隐传呢?

How is iWantA different from iWantInt ? 如何iWantA从不同iWantInt Why does it not work the same way ? 为什么它的工作方式不一样?

Is this behavior documented/explained somewhere ? 这种行为是在某处记录/解释的吗?

If Scala would accept iWantInt(a) what kind of problems would that cause ? 如果Scala接受iWantInt(a)会导致什么样的问题? Why is it forbidden ? 为什么禁止它?

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
}

Instead of defining an implicit conversion, A2Int acts like a value that has been declared implicit, like implicit val a in the example, the only difference being that an implicit A must be discovered in scope for it to work. 而不是定义隐式转换, A2Int就像一个已声明为隐式的值,如示例中的implicit val a ,唯一的区别是必须在范围内发现隐式A才能使其工作。 This is what allows iWantInt without an explicit parameter to compile - the compiler finds A2Int as the implicit Int , then finds a as the implicit A for A2Int . 这是允许iWantInt没有显式参数进行编译的原因 - 编译器将A2Int作为隐式Int发现,然后找到a作为A2Int的隐式A

For a function to qualify as an implicit conversion it must take a single non-implicit parameter. 对于有资格作为隐式转换的函数,它必须采用单个非隐式参数。 B2Int takes the single parameter (b: B) and so meets the requirement. B2Int采用单个参数(b: B) ,因此符合要求。 This allows iWantInt(b) to compile. 这允许iWantInt(b)进行编译。 A2Int has (implicit a: A) but because this parameter is implicit A2Int does not meet the requirement and so iWantInt(a) does not compile, unless a line like implicit def A2Int2(a:A) = 1 is added. A2Int具有(implicit a: A)但因为该参数是隐含A2Int不符合要求,所以iWantInt(a)不编译,除非像线implicit def A2Int2(a:A) = 1被添加。 If you run scalac with the -feature flag (which it will suggest at least with 2.11) it will display warnings for B2Int and A2Int2 , saying that implicit conversions should be explicitly enabled by making visible scala.language.implicitConversions . 如果您使用-feature标志运行scalac (它至少建议使用2.11),它将显示B2IntA2Int2警告,表示应通过显示scala.language.implicitConversions显式启用隐式转换。 It does not show the warning for A2Int , demonstrating that the compiler does not treat it as an implicit conversion. 它没有显示A2Int的警告,表明编译器不会将其视为隐式转换。

The Scala Language Reference is the definitive definition for Scala. Scala语言参考Scala的最终定义。 See Chapter 7, "Implicit Parameters and Views" for the specification of how these particular features behave. 有关这些特定功能的行为规范,请参见第7章“隐式参数和视图”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM