Scala隐式参数,默认值在随播对象中定义

时间:2011-01-20 16:23:39

标签: scala scope implicit

根据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
  }
}

1 个答案:

答案 0 :(得分:9)

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

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")
  }
}

在规范的第7.2节中似乎很清楚:

  

符合条件的实际参数   要传递给隐式参数   T型分为两类。   首先,符合条件的是所有标识符x   可以访问的点   方法调用没有pre fi x和   这表示隐含的定义   (§7.1)或隐含参数。一个   因此,符合条件的识别可以是本地的   姓名或附件的成员   模板,或者它可能已经制作完成   无需预先通过   import子句(§4.7)。如果没有   符合此规则的合格身份证明,   那么,第二,符合条件的也是全部   某些对象的隐式成员   属于隐含的范围   隐式参数的类型,T。

您能引用指示定义的包含类的伴随对象的部分吗?