2015-10-24 73 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'成员不能。我相信还有很多其他的区别。 –