【问题标题】:Unambiguous Subimplicits明确的子隐式
【发布时间】:2012-11-23 09:40:49
【问题描述】:

考虑以下代码:

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 不会引发ambiguous implicit values 错误。当然

implicit val b: A = new B

会引发该错误。为什么foo 选择隐含的b 而不是隐含的a?或者更笼统的说:选择什么规则是什么?

编辑:
由于我与 Ivan 的评论对话,我想澄清一下:如果我以与隐式方法参数相同的方式命名本地隐式 val,我会知道我的问题的答案。

def bar(implicit a: A) = {
  implicit val a = new B
  foo
}

那么只有本地的val a 在范围内覆盖方法参数,因为它们具有相同的名称。

【问题讨论】:

标签: scala implicit


【解决方案1】:

注意:我可能过于简单化了,但在测试中它似乎如下所示。

这是因为第二个在内部范围内,所以它具有优先级。与

发生的事情是一样的
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

【讨论】:

  • 有趣的观点!范围:是的,我虽然是这样,但在我的理解中,方法参数与在同一方法中定义的本地 vals/vars 在同一范围内。您的示例使它们超出了范围。那么优先级对我来说非常清楚。现在我很好奇:方法参数是否与本地方法 vals/vars 不在同一范围内,还是对 scala 中的隐式进行特殊处理?
  • 我更新了我的答案。本地 val 优先于方法参数。
  • 我明白了:当本地 val 具有相同的名称(平凡)时,它们优先于方法参数,类似于本地隐式在它们都适合且具有相同名称时优先于方法参数的隐式。
  • 但是,就我而言,它们没有相同的名称,如果我只将类型注释从 implicit val b: B = new B 更改为 implicit val b: A = new B 并引发错误,尽管我没有更改与范围界定有关。对我来说,它似乎处理子类化,而不仅仅是范围(你指出这也很重要)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2021-01-20
相关资源
最近更新 更多