6

我对 Joshua Suareth 的书 Scala 中的“5.1.3 隐式解析”中的描述感到困惑,第 100 页:

Scala 对象不能有隐含的伴随对象。因此,必须从外部范围提供与该对象类型的隐式范围所需的与对象类型关联的隐式。这是一个例子:

scala> object Foo {
     |   object Bar { override def toString = "Bar" }
     |   implicit def b : Bar.type = Bar 
     |}
defined module Foo
scala> implicitly[Foo.Bar.type]
res1: Foo.Bar.type = Bar

但是当我在 REPL 中隐含对象 Bar 时:

scala> object Foo {
     |   implicit object Bar {
     |     override def toString = "isBar" }
     | }
defined module Foo
scala> implicitly[Foo.Bar.type]
res0: Foo.Bar.type = isBar

似乎不需要在外部范围内定义一个隐式。还是我完全错误地理解了约书亚的意思?

4

2 回答 2

8

在这种情况下,对象的行为就好像它们是它们自己的同伴一样,因此您只需将对象类型提及隐式嵌套在对象本身的主体中,

scala> object Bar {
     |   override def toString = "Bar"
     |   implicit def b : Bar.type = Bar
     | }
defined module Bar

scala> implicitly[Bar.type]
res0: Bar.type = Bar

请注意,此处的主体Bar已被视为解析的隐式范围的一部分Bar.type

这可能看起来是 Scala 类型系统的一个不起眼的角落,但我能够在shapeless的多态(函数)值编码中很好地使用它。

于 2013-03-19T13:46:08.497 回答
2

如果您将以下代码放在文件中并尝试使用scalac它进行编译,则会失败并显示'implicit' modifier cannot be used for top-level objects

 implicit object Foo {
  object Bar { override def toString = "Bar" }
 }

然而,这编译得很好:

 object Foo {
  implicit  object Bar { override def toString = "Bar" }
 }

我相信使用REPL implicit's不完全是顶级的,因此看起来不一致。

于 2013-03-19T12:12:19.600 回答