2016-04-05 14 views
6

Tôi đang cố thêm các chức năng mới vào các kiểu hiện có (vì vậy tôi có thể tự động đề xuất các chức năng có liên quan cho các loại tôi không kiểm soát, ví dụ Future[Option[A]]). Tôi đã khám phá cả hai lớp ngầm định và chuyển đổi ngầm để thực hiện điều này và cả hai dường như cung cấp cùng một hành vi.Implicit class vs Implicit chuyển đổi thành đặc điểm

Có sự khác biệt hiệu quả giữa việc sử dụng một lớp ẩn:

case class Foo(a: Int) 
implicit class EnrichedFoo(foo: Foo) { 
    def beep = "boop" 
} 
Foo(1).beep // "boop" 

Và sử dụng một chuyển đổi ngầm:

case class Foo(a: Int) 
trait Enriched { 
    def beep: String 
} 
implicit def fooToEnriched(foo: Foo) = new Enriched { 
    def beep = "boop" 
} 
Foo(1).beep // "boop" 

Tôi cho rằng một sự khác biệt ở đây có thể là ví dụ đầu tiên tạo ra một one- tắt lớp thay vì một đặc điểm, nhưng tôi có thể dễ dàng điều chỉnh lớp ẩn để mở rộng đặc điểm trừu tượng, ví dụ:

case class Foo(a: Int) 
trait Enriched { 
    def beep: String 
} 
implicit class EnrichedFoo(foo: Foo) extends Enriched { 
    def beep = "boop" 
} 
Foo(1).beep // "boop" 

Trả lời

5

Theo như tôi biết, chúng khá giống nhau. Các quy tắc phạm vi cũng áp dụng cho cả hai.

Theo ý kiến ​​của tôi, tôi sẽ sử dụng số implicit classes cho loại tình huống của bạn. Chúng có thể được tạo ra chính xác cho một cái gì đó như thế.

Chuyển đổi tiềm ẩn, với tôi, phù hợp hơn khi bạn đã thực sự có hai loại lớp khác nhau và muốn chuyển đổi giữa hai loại.

Bạn có thể kiểm tra đề nghị ban đầu cho các lớp ngầm right here. Có nó nói:

Một cấu trúc ngôn ngữ mới được đề xuất để đơn giản hóa việc tạo ra các lớp học cung cấp phương pháp khuyến nông để loại khác.

Bạn thậm chí có thể xem nó như thế nào desugars implicit classes. Sau đây:

implicit class RichInt(n: Int) extends Ordered[Int] { 
    def min(m: Int): Int = if (n <= m) n else m 
    ... 
} 

sẽ desugar thành:

class RichInt(n: Int) extends Ordered[Int] { 
    def min(m: Int): Int = if (n <= m) n else m 
    ... 
} 
implicit final def RichInt(n: Int): RichInt = new RichInt(n) 
+1

Một điều nữa cần lưu ý là, khi bạn muốn chuyển đổi hoàn toàn đối tượng kiểu A thành đối tượng thuộc loại B, trong đó B là một 'lớp cuối cùng' *, một' ngầm định' là lựa chọn duy nhất của bạn. – Adowrath

0

Vâng với tôi một vấn đề của sở thích. Trên thực tế, implicit classes xuất hiện để dễ dàng tạo ra các lớp cung cấp các phương thức mở rộng cho một kiểu khác. Các lớp ngầm định thêm nhiều giá trị vào value classes.

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