Scala 明确次隐式
考虑以下代码:Scala 明确次隐式,scala,implicit,Scala,Implicit,考虑以下代码: class A { def print = println("A") } class B extends A { override def print = println("B") } def foo(implicit a: A) = a.print def bar(implicit a: A) = { implicit val b = new B foo } bar(new A) // B 我想知道为什么在bar中调用foo不会引发不明确的隐式值错误。当然 im
class A { def print = println("A") }
class B extends A { override def print = println("B") }
def foo(implicit a: A) = a.print
def bar(implicit a: A) = {
implicit val b = new B
foo
}
bar(new A) // B
我想知道为什么在bar
中调用foo
不会引发不明确的隐式值
错误。当然
implicit val b: A = new B
将引发该错误。为什么foo
选择隐式b
而不是隐式a
?或者更一般地说:规则是什么?挑选什么
编辑:由于我与Ivan的评论对话,我想澄清一下:如果我以与隐式方法参数相同的方式命名局部隐式val,我将知道问题的答案
def bar(implicit a: A) = {
implicit val a = new B
foo
}
然后,只有本地
val a
在作用域中,作用域覆盖了方法参数,因为它们具有相同的名称。注意:我可能过度简化了事情,但在测试中,它似乎如下所示
因为第二个在内部范围内,所以它有优先权。这和我们在一起发生的事情是一样的
object test {
val a = 5
def test(i: Int) = {
val a = 6
i + a
}
}
在这种情况下,您希望函数中的a
为6。以下是类似的
object test {
implicit val i = 5;
{
implicit val b = 6;
test
}
def test(implicit ii:Int) = println(ii)
}
根据评论更新
scala> def test(a: Int) = {val a = 5; a }
test: (a: Int)Int
scala> test(6)
res1: Int = 5
可能重复的请参阅(从该问题链接)。有趣的观点!范围界定:是的,我想是这样,但据我所知,方法参数与同一方法中定义的本地VAL/VAR在同一范围内。你的例子超出了范围。那我就很清楚了。现在我很好奇:方法参数是否与本地方法VAL/VAR不在同一范围内,或者它是scala中隐式的特殊处理方法?我更新了我的答案。本地VAL优先于方法参数。我明白了:当方法参数具有相同的名称(平凡)时,本地VAL优先于方法参数,类似于本地隐式。当它们都适合并且具有相同的名称时,本地VAL优先于方法参数隐式。但是,在我的例子中,它们没有相同的名称,如果我只将类型注释从
implicit val b:b=new b
更改为implicit val b:A=new b
,则会出现错误,尽管我没有更改与作用域有关的内容。对我来说,它似乎涉及子类化,而不仅仅是范围界定(你指出,这一点也很重要)