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
,则会出现错误,尽管我没有更改与作用域有关的内容。对我来说,它似乎涉及子类化,而不仅仅是范围界定(你指出,这一点也很重要)