2011-12-15 24 views
5

Trong chương 22 của "Lập trình trong Scala" cuốn sách, :: lớp (khuyết điểm) được định nghĩa làdùng mới với Scala thức trường hợp lớp

final case class ::[T](hd: T, tl: List[T]) extends List[T] { 
    //... 
} 

Phương pháp :: trong lớp List được định nghĩa như sau:

def ::[U >: T](x: U): List[U] = new scala.::(x, this) 

Tại sao new cần thiết để tạo một thể hiện của các finalcaseclass ::? Đây có phải là hoàn toàn cho sự định hướng?

+4

cuối cùng chỉ có nghĩa là lớp không thể được mở rộng, nó không có gì để làm với tạo ví dụ :-). Trường hợp lớp cơ bản là một lớp có thể được so sánh trong một khối 'trường hợp phù hợp'. – aishwarya

Trả lời

6

Với trường hợp các lớp học bạn sẽ tự động nhận được một đối tượng đồng mà apply phương pháp gọi các nhà xây dựng, trong cùng một cách như bạn có thể làm điều này với một lớp học bình thường:

class Foo(val value: Int) 
object Foo { def apply(value: Int) = new Foo(value) } 

val x = new Foo(42) // 
val y = Foo(42)  // both work the same 

Bạn có thể nhanh chóng lớp trường hợp với new nếu bạn muốn. Nó có thể về lý thuyết nhanh hơn một chút bởi vì nó không phải đi qua phương pháp apply của đối tượng đồng hành, nhưng tôi đã thử một điểm chuẩn nhanh và thấy hoàn toàn không có sự khác biệt về hiệu năng, vì vậy tôi đoán nó được tối ưu hóa bởi trình biên dịch, hoặc chỉ là một sự khác biệt so với việc xây dựng thực tế.

Vì vậy, tôi không nghĩ rằng new trong ví dụ bạn đưa ra có bất kỳ ý nghĩa nào và cũng có thể được bỏ qua.

3

Bạn là chính xác; new không bắt buộc. Họ có thể đã xác định phương pháp dụ List#:: như thế này chỉ là tốt:

def ::[U >: T](x: U): List[U] = scala.::(x, this) 

(Lưu ý rằng chúng ta có:

type :: = collection.immutable.:: 
val :: = collection.immutable.:: 

quy định tại đối tượng scala gói; là người đầu tiên là tại sao new scala.::(x, this) tác phẩm của mình, và thứ hai là lý do tại sao công cụ scala.::(x, this) của tôi hoạt động.)

The form the library uses gọi trực tiếp cho nhà xây dựng, như của bạn. Phương thức thay thế gọi phương thức apply của đối tượng đồng hành tổng hợp được tạo cho lớp trường hợp ::, mà chỉ đơn giản gọi hàm tạo. Có lẽ gọi nhà xây dựng được coi là rõ ràng hơn, hoặc hiệu quả hơn? (. Tăng hiệu quả nên được gần gũi với không có gì, tuy nhiên, vì nếu trình biên dịch không nội tuyến cuộc gọi đến apply, JVM sẽ) Tôi cho rằng các hình thức nhỏ gọn nhất:

def ::[U >: T](x: U) = ::(x, this) 

có thể bị nhầm lẫn với một số lập dị (Ví dụ, không thể) loại lời gọi đệ quy, và ở bất kỳ tỷ lệ nào làm mờ sự khác biệt giữa các lớp được gọi là :: và phương pháp List được gọi là ::, mà Giáo sư Odersky chịu đựng để giữ riêng biệt nhằm tối đa hóa khả năng đọc của người đọc.

Hy vọng điều này sẽ hữu ích.

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