8

根据 Scala Spec (2.8),要找到隐式,它必须在本地范围、继承范围或伴随对象中定义。鉴于此,在我看来,以下代码应该在没有显式导入伴随对象内容的情况下工作。我在 Scala 库源代码(例如 CanBuildFrom)中看到了这个。似乎我应该能够从 XX 类的定义之外调用 XX.foo() 并使用来自伴随类的隐式参数。我错过了什么?

object XX {
   implicit def XYZ[T]: (T) => Unit = null
}

class XX {
  // import XX._     // Works with this line uncommented...
  def foo(s: String)(implicit f: (String) => Unit): Unit = {
    if (f == null)
      println("Just: " + s)
    else
      f(s)
  }

  def bar {
    foo("abc"){ s => println("Func: " + s)}
    foo("xyz")  // <-- Compile error here: could not find implicit value for parameter f
  }
}
4

1 回答 1

10

我总是将规范解释为意味着可以在隐式参数的伴随对象中定义隐式,而不是包含定义的类。像这样的东西:

object ZZ {
   implicit val xyz: ZZ = new ZZ()
}
class ZZ {
  def bar: (String) => Unit = null
}

class XX {
  def foo(s: String)(implicit f: ZZ): Unit = {
    if (f.bar == null)
      println("Just: " + s)
    else
      f.bar(s)
  }

  def bar {
    foo("xyz")
  }
}

It seems clear in Section 7.2 of the spec:

The actual arguments that are eligible to be passed to an implicit parameter of type T fall into two categories. First, eligible are all identifiers x that can be accessed at the point of the method call without a prefix and that denote an implicit definition (§7.1) or an implicit parameter. An eligible identifiermay thus be a local name, or a member of an enclosing template, or it may be have been made accessible without a prefix through an import clause (§4.7). If there are no eligible identifiers under this rule, then, second, eligible are also all implicit members of some object that belongs to the implicit scope of the implicit parameter’s type, T.

Can you quote the part that indicates the companion object of the containing class of the definition?

于 2011-01-20T16:44:01.353 回答