Scala 隐式参数,其默认值在伴生对象中定义

发布于 2024-10-13 04:59:12 字数 646 浏览 4 评论 0原文

根据 Scala 规范 (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
  }
}

According to the Scala Spec (2.8), for an implicit to be found it must be defined in local scope, inherited scope, or in a companion object. Given that, it seems to me that the following code should work without an explicit import of the contents of the companion object. I see this used in the Scala library source (eg. CanBuildFrom). It also seems that I should be able to call XX.foo() from outside the definition of the XX class and have my implicit parameter from the companion class used. What am I missing?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱要勇敢去追 2024-10-20 04:59:12

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

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
可以在以下位置访问
没有前缀的方法调用和
表示隐式定义
(§7.1) 或隐式参数。一个
因此,合格的标识符可能是本地的
名称,或封闭的成员
模板,或者可能已经制作好了
无需前缀即可通过
进口条款(§4.7)。如果没有
本规则下的合格标识符,
那么,第二,符合条件的也都是
某些对象的隐式成员
属于隐式范围
隐式参数的类型,T。

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

I always interpreted the spec to mean that the implicit can be defined in the companion object of the implicit parameter, not the class containing the definition. Something like this:

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文