为什么隐式参数在进行隐式转换时不能显式传递? [英] Why implicit parameters cannot be passed explicitly when they undergo an implicit conversion?
问题描述
为什么iWantInt(a)
不能在iWantInt(b)
时编译,并且-更令人惊讶的是-iWantInt
可以编译吗?
Why iWantInt(a)
does not compile while iWantInt(b)
and - what is more surprising - iWantInt
does ?
我如何理解这种行为?
为什么我可以隐式传递a
到iWantInt
吗?
Why can I not pass explicitly a
to iWantInt
when I can pass it implicitly ?
iWantA
与iWantInt
有何不同?为什么它不能以相同的方式工作?
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),它将显示B2Int
和A2Int2
的警告,表示应通过使可见的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屋!