2013-03-19 87 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是不完全是頂級的,因此看起來不一致。