2013-03-19 107 views
6

对象,我通过在约书亚Suareth的书斯卡拉深入“5.1.3隐式解析,”这说明迷茫,在第100页:implicits在斯卡拉

斯卡拉对象不能有同伴对象implicits。因为 这个,与对象的类型相关的暗示, 需要该对象类型的隐式范围,所以必须从外部作用域提供 。这里有一个例子:

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隐:

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

看来,它并不需要在外部范围定义一个隐含的。或者我认为约书亚的意思完全错了?

+1

书的写作时间和您使用的是哪个版本的Scala?这可能在2.9或2.10中有所改变。 – KChaloux 2013-03-19 13:15:10

+1

事情至少从2.9.x开始,至少在我的答案中。 Josh一定是指2.9以前的Scala,或者只是没有意识到语义。当我发现这是可能的时候,FTR我既惊又喜。 – 2013-03-19 13:56:45

+0

感谢您的回复。本书建议它涵盖2.7.x到2.9.x.我的机器上安装了2.10,可能会有不同的表现。 – cfchou 2013-03-19 15:32:37

回答

8

在这种情况下对象的行为,好像他们是自己的同伴,所以你只需要嵌套的对象类型提的是在对象本身的身体implicits,

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

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

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