Hãy nhìn vào limitations listed for value classes và suy nghĩ khi họ có thể không phù hợp cho các lớp ẩn:
"phải chỉ có một nhà xây dựng chính với chính xác một cộng đồng, tham số val có loại không phải là một lớp học giá trị. " Vì vậy, nếu lớp bạn đang gói là chính nó một lớp giá trị, bạn không thể sử dụng một implicit class
như là một wrapper, nhưng bạn có thể làm điều này:
// wrapped class
class Meters(val value: Int) extends AnyVal { ... }
// wrapper
class RichMeters(val value: Int) extends AnyVal { ... }
object RichMeters {
implicit def wrap(m: Meter) = new RichMeter(m.value)
}
Nếu wrapper của bạn có các thông số ngầm là tốt, bạn có thể thử di chuyển chúng đến các khai báo phương thức. I E. thay vì
implicit class RichFoo[T](foo: Foo[T])(implicit ord: Ordering[T]) {
def bar(otherFoo: Foo[T]) = // something using ord
}
bạn có
implicit class RichFoo[T](foo: Foo[T]) extends AnyVal {
def bar(otherFoo: Foo[T])(implicit ord: Ordering[T]) = // something using ord
}
"có thể không có tham số kiểu đặc biệt." Bạn có thể muốn trình bao bọc được chuyên môn hóa khi gói một lớp mà chính nó có các tham số kiểu đặc biệt.
- "có thể không có các lớp, đặc điểm hoặc đối tượng địa phương lồng nhau hoặc" Một lần nữa, một thứ có thể hữu ích cho việc triển khai trình bao bọc.
- "không được xác định phương thức
equals
hoặc hashCode
". Không liên quan, vì các lớp ngầm cũng không nên có equals/hashCode
.
- "phải là một lớp cấp cao nhất hoặc là thành viên của đối tượng có thể truy cập tĩnh" Đây cũng là nơi bạn thường định nghĩa các lớp ẩn, nhưng không bắt buộc.
- "chỉ có thể có defs như các thành viên. Đặc biệt, nó không thể có lười biếng vals, vars, hoặc vals là thành viên." Các lớp ngầm định có thể có tất cả các lớp đó, mặc dù tôi không thể nghĩ ra một số lần sử dụng hợp lý cho
var
s hoặc lazy val
s.
- "không thể được mở rộng bởi một lớp khác". Một lần nữa, các lớp ngầm có thể được mở rộng, nhưng có lẽ không có lý do chính đáng để.
Ngoài ra, làm cho lớp tiềm ẩn của bạn một lớp giá trị có thể có thể thay đổi một số hành vi của mã bằng cách sử dụng sự phản chiếu, nhưng phản ánh không thường thấy các lớp ngầm định.
Nếu lớp ngầm của bạn đáp ứng tất cả các giới hạn đó, tôi không thể nghĩ ra lý do để không biến nó trở thành một lớp giá trị.
Nguồn
2013-02-18 07:23:20
fwiw, đây là trường hợp sử dụng cho 'lazy val' bên trong' lớp ẩn ': https: //gist.github.com/SethTisue/8977033. May mắn thay có một cách giải quyết dễ dàng (cũng được thể hiện trong ý chính). –
"Tôi không thể nghĩ ra một lý do nào để không biến nó trở thành một lớp giá trị." - bởi vì nó mất tập trung nhưng không mang lại lợi ích gì. Tôi đã không thể tái tạo các lợi ích bộ nhớ được giả định của "extends AnyVal" các lớp ngầm định trong các bài kiểm tra của tôi. Bạn có một trích dẫn cho những lợi ích? – Rich
Tài liệu này vẫn đề xuất, nhưng tôi không thể đo lường bất kỳ lợi ích nào trong các bài kiểm tra của mình. http://docs.scala-lang.org/overviews/core/value-classes.html – Rich