2015-10-24 19 views
17

Tôi đã thấy hai cách (một cách nhỏ hơn cách khác) tuyên bố implicit cho mẫu chữ số trong Scala.Đối tượng tiềm ẩn Scala vs implicit val

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

Chúng khác nhau như thế nào? Nên một người thích cái này cho người khác trong một thời gian nhất định? Tôi tìm thấy implicit val thường được sử dụng nhiều hơn implicit object và tôi chưa tìm thấy nhiều tài nguyên về implicit object.

Trả lời

8

Một khác biệt là phiên bản object sẽ được khởi chạy một cách lười biếng, nghĩa là hàm khởi tạo của nó sẽ không được gọi cho đến lần đầu tiên được sử dụng. Ví dụ:

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 
} 

Lưu ý rằng bạn sẽ không thấy thông báo từ IntIncrementer cho đến khi được sử dụng, ví dụ:

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

Thông báo từ DoubleIncrementer, tuy nhiên, sẽ được hiển thị khi được xác định. Vì vậy, việc khởi tạo implicit object là lười trong khi khởi tạo implicit val là nghiêm ngặt.

+1

Vì vậy, quyết định sử dụng 'đối tượng' ẩn 'so với' val' phụ thuộc vào việc có nên khởi tạo lười biếng hay nghiêm ngặt không? –

+2

Đó có thể là một sự cân nhắc (mặc dù bạn luôn có thể sử dụng 'lazy val' để có được sự lười biếng với một' val'), nhưng không phải là duy nhất. Ví dụ, một thành viên 'val' có thể được ghi đè trong một lớp con trong khi một thành viên' object' không thể. Tôi chắc chắn có rất nhiều sự khác biệt khác. –

Các vấn đề liên quan