2015-10-24 17 views
17

Scala'da tipeclass desen için implicit bildirmesinin iki yolu (biri diğerinden daha az) gördüm.Scala implicit nesnesi vs örtülü değer

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

Nasıl farklılar? Belirli zamanlarda biri diğerine mi tercih edilir? Ben implicit object daha yaygın olarak kullanılan implicit val buluyorum ve henüz implicit object hakkında birçok kaynak bulmak için bulduk.

cevap

8

Tek fark, object versiyonunun tembel olarak başlatılacağı, yani ilk kez kullanılıncaya kadar kurucunun çağrılmayacağıdır.

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 
} 

kullanıldığı kadar IntIncrementer mesajı görmezsiniz Not örn: Örneğin Bu tanımlandığı zaman

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

DoubleIncrementer gelen mesaj Ancak görüntülenecektir. Bu nedenle implicit object'un başlatılması, implicit val'un başlatılması sıkıdır.

+1

Yani, “örtülü” nesneyi “val” ile kullanma kararı, tembel veya katı başlatmayı tercih edip etmeyeceğine mi bağlı? –

+2

Bu, tek bir düşünce olabilir (her zaman tembel val' ile tembellik yapmak için bir "val" kullanabilirsiniz), ama tek değil. Örneğin, bir 'nes' üyesi, bir alt nesne içinde bir 'nesne' üyesi yapamazken geçersiz kılınabilir. Eminim başka farklılıklar da var. –