2015-10-24 71 views
17

我見過兩種方式(一個比另一個)聲明implicit類型類型斯卡拉。斯卡拉隱式對象vs隱式val

implicit val instance1 = new Typeclass { def do = ??? } 
implicit object instance2 extends Typeclass { def do = ??? } 

它們有什麼不同?在某些時候,人們應該選擇另一個嗎?我發現implicit valimplicit object更常用,我還沒有找到關於implicit object的許多資源。

回答

8

一個區別是object版本將被延遲初始化,即它的構造函數在第一次使用前不會被調用。例如:

trait Incrementer[T] { 
    def inc(x: T) 
} 

def increment[T](x: T)(implicit ev: Incrementer[T]) = ev.inc(x) 

implicit object IntIncrementer extends Incrementer[Int] { 
    println("IntIncrementer is being constructed...") 

    def inc(x: Int) = x + 1 
} 

implicit val DoubleIncrementer extends Incrementer[Double] { 
    println("DoubleIncrementer is being constructed...") 

    def inc(x: Double) = x + 1D 
} 

請注意,你不會看到IntIncrementer消息被使用到,例如

increment(1) //this prints "IntIncrementer is being constructed..." 

DoubleIncrementer該消息,但是,將被定義時顯示。所以implicit object的初始化是懶惰的,而implicit val的初始化是嚴格的。

+1

因此,決定使用隱式對象與val來取決於是否更喜歡懶惰或嚴格的初始化? –

+2

這可能是一個考慮因素(儘管你總是可以用'lazy val'來獲得'val'的懶惰),但不是唯一的。例如,'val'成員可以在子類中重寫,而'object'成員不能。我相信還有很多其他的區別。 –