我对Joshua Suareth的书Scala中的“5.1.3隐式解决方案”中的描述感到困惑,第100页:
Scala对象不能包含implicits的伴随对象。因为 这,与期望的对象类型相关的隐含 该对象类型的隐式范围必须由a提供 外部范围。这是一个例子:
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
似乎它不需要在外部范围中定义隐式。或者我认为约书亚的意思完全错了?
答案 0 :(得分: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的polymorphic (function) values编码中充分利用它。
答案 1 :(得分: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
并不完全是顶层因此看似不一致。