为什么隐式参数在进行隐式转换时不能显式传递? [英] Why implicit parameters cannot be passed explicitly when they undergo an implicit conversion?

查看:207
本文介绍了为什么隐式参数在进行隐式转换时不能显式传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么iWantInt(a)不能在iWantInt(b)时编译,并且-更令人惊讶的是-iWantInt可以编译吗?

Why iWantInt(a) does not compile while iWantInt(b) and - what is more surprising - iWantInt does ?

我如何理解这种行为?

为什么我可以隐式传递aiWantInt吗?

Why can I not pass explicitly a to iWantInt when I can pass it implicitly ?

iWantAiWantInt有何不同?为什么它不能以相同的方式工作?

How is iWantA different from iWantInt ? Why does it not work the same way ?

此行为是否在某处得到记录/解释?

Is this behavior documented/explained somewhere ?

如果Scala接受iWantInt(a),那会导致什么问题?为什么禁止它?

If Scala would accept iWantInt(a) what kind of problems would that cause ? 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
}

推荐答案

A2Int而不是定义隐式转换,其作用类似于已声明为隐式的值,例如本例中的implicit val a,唯一的不同是必须在作用域中发现隐式A才能起作用.这就是允许iWantInt在没有显式参数的情况下进行编译的原因-编译器将A2Int查找为隐式Int,然后将a查找为隐式A对于A2Int.

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. 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.

要使函数具有隐式转换的资格,它必须使用单个非隐式参数. 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的警告,表明编译器未将其视为隐式转换.

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. This allows iWantInt(b) to compile. 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. 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. It does not show the warning for A2Int, demonstrating that the compiler does not treat it as an implicit conversion.

Scala语言参考是明确的定义对于Scala.有关这些特殊功能的行为的规范,请参见第7章,隐式参数和视图".

The Scala Language Reference is the definitive definition for Scala. See Chapter 7, "Implicit Parameters and Views" for the specification of how these particular features behave.

这篇关于为什么隐式参数在进行隐式转换时不能显式传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆