2011-12-12 32 views
9

class C [+T] { var v : T = _ } howto khởi tạo biến covariant?

trình biên dịch báo lỗi: hiệp biến kiểu T xảy ra ở vị trí contravariant trong loại T có giá trị value_ =

tại sao? làm thế nào tôi có thể sửa chữa nó?

Trả lời

17

Bạn không thể có var của loại biến đổi. Một số lượng var có, trong số những thứ khác, một công khai def v_=(newV: T), do đó, nó làm cho T xuất hiện như là một đối số thường xuyên, đó là một vị trí contravariant. Vì vậy, bạn phải

  • từ bỏ hiệp phương sai và tuyên bố C [T] chứ không phải C [+ T]
  • làm va val

Để có một chút tiết thêm về "tại sao" một phần của câu hỏi của bạn, bằng cách đặt T là thông số covariant với + T, bạn nói rằng bạn muốn C [B] thành aa kiểu con của C [A] nếu B là kiểu con của A. Điều này có nghĩa là bạn muốn cho phép:

val cb: C[B] = new C[B] 
val ca : C[A] = cb  

Để làm cho âm thanh này, trình biên dịch hạn chế nơi T có thể xuất hiện trong C. Để làm cho nó ngắn và với sự đơn giản nhỏ, v không thể xuất hiện như là tham số của một thói quen (hoặc là loại của một var). Nếu không, sau khi bạn đã khởi tạo cb và ca như đã mô tả ở trên, bạn coulddo

ca.v = new A 

này sẽ được phép, như ca được coi là một C[A], vì vậy nó biến v là loại A. Tuy nhiên, như C là covariant trong T, ca có thể (và trong ví dụ) tham chiếu một cá thể C[B]. nhiệm vụ này sẽ được phép, sau đó bạn có thể làm

val vInCb: B = cb.v 

tin tưởng rằng đây sẽ cho bạn một B. Tuy nhiên, bạn chỉ cần đặt một số A ở đó thông qua tham chiếu ca. Tình trạng này phải bị cấm, và nó là, bằng cách cấm tham số kiểu biến đổi T là kiểu của một var.

+0

Có một lựa chọn thứ ba ... –

+0

Cảm ơn rất nhiều Daniel, tôi đã viết một biến thể thứ ba với tư nhân và gỡ bỏ nó sau khi thử nghiệm, tôi đã quên [this] –

2

Bạn phải đặt số val. A var luôn có phương thức setter nơi kiểu xuất hiện ở vị trí contravariant.

9

Bạn có thể khai báo nó như private[this]:

class C [+T] { private[this] var v : T = _ } 

Bất kỳ việc sử dụng bạn cố gắng mà phạm vi này không cho phép sẽ không an toàn với một đồng biến T.

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