在Scala中隐含对象

时间:2013-03-19 11:37:14

标签: scala object implicit

我对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

似乎它不需要在外部范围中定义隐式。或者我认为约书亚的意思完全错了?

2 个答案:

答案 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类型系统的一个模糊角落,但我能够在shapelesspolymorphic (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并不完全是顶层因此看似不一致。