2011-08-17 26 views
6

Tôi muốn xuất phát từ Bản đồ bất biến của Scala. Nó được định nghĩa như vậy:Có thể thay đổi phương sai của một lớp/đặc điểm cơ bản trong Scala không?

trait Map[A, +B] 

Thật không may, thực hiện của tôi cần phải được bất biến trong B. Tôi cố gắng điều sau đây, nhưng không thành công:

def +(kv : (A, B)) : MyMap[A, B] = { ... } 

override def +[B1 >: B](kv : (A, B1)) : MyMap[A, B1] = 
    throw new IllegalArgumentException() 

Có lẽ đó là một thủ thuật với @uncheckedVariance?

+1

Có thể bạn có thể sử dụng bản đồ thành viên thay vì phát sinh? – Owen

+0

Ngoài ra, tại sao nó cần phải là bất biến? Tôi nghĩ (tôi không biết nhiều Scala mặc dù) thời gian duy nhất bạn cần bất biến là nếu nó có thể là cả nguồn và bồn rửa, nhưng bản đồ là bất biến nên nó không thể là bồn rửa được. – Owen

+0

Tôi muốn thực hiện một bản đồ hai hướng. Không phải là một vấn đề lớn nếu tôi triển khai Bản đồ và chỉ ủy nhiệm cho hai Maps nội bộ xác định ánh xạ tiến và lùi, nhưng tôi cần sự bất biến trong trường hợp đó. –

Trả lời

1

Loại bỏ hiệp phương sai hoàn toàn dĩ nhiên sẽ không được phép và không được phép. Cho m: Map[A, String]v : Any, bạn có thể làm val mm : Map[A, Any] = m + v. Đây là định nghĩa của Map và tất cả những người triển khai phải tuân theo. Lớp của bạn có thể là bất biến, nhưng nó phải thực hiện giao diện biến đổi đầy đủ của Bản đồ.

Bây giờ xác định lại + để ném lỗi là một câu chuyện khác (chưa được phát âm). Vấn đề với phương pháp + mới của bạn là sau khi generics xóa, nó có cùng chữ ký so với phương thức + khác. Có một thủ thuật: thêm vào tham số ngầm, để bạn có hai tham số trong chữ ký, điều này làm cho nó khác với thông số đầu tiên.

def +(kv : (A,B))(implicit useless: A <:< A) : MyMap[A,B] 

(nó không thực sự có vấn đề gì tiềm ẩn tham số bạn đang tìm kiếm, chừng nào một được tìm thấy implicit useless: Ordering[String]. Hoạt động giống cũng)

Làm như vậy, bạn có vấn đề thông thường với quá tải . Nếu bạn thêm một B mà không có trình biên dịch biết nó là như vậy, phương thức thất bại sẽ được gọi. Nó có thể là tốt hơn để thực hiện một loại kiểm tra có để B trường hợp được chấp nhận bất cứ điều gì. Điều đó sẽ yêu cầu nhận được một bản kê khai [Manifest [B] trong bản đồ của bạn.

3

Vấn đề là nếu bạn lấy được một phiên bản bất biến từ bản đồ không thay đổi, bạn sẽ phá vỡ an toàn loại. Ví dụ:

val dm = DiotMap(1 -> "abc") 
val m: Map[Int, Any] = dm 

Tuyên bố này có giá trị, vì Map là biến thể. Nếu bộ sưu tập của bạn không thể xử lý hiệp phương sai, điều gì sẽ xảy ra khi tôi sử dụng m?

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