2011-01-06 32 views
5

Mã scala sau có vẻ là hợp lệ:Lỗi trong hệ thống kiểu của Scala?

class A[X] 
class C[M[X] <: A[X]] 

class Main 

new C[A] 

tôi mong đợi các trình biên dịch để thực hiện suy luận kiểu trên loại A, nhưng sau khi tôi thử như sau:

new C[A[Int]] 

tôi nhận được thông báo lỗi sau :

(fragment of Main.scala):11: error: this.A[Int] takes no type parameters, expected: one 
println(new C[A[Int]]) 

Trả lời

2

Bạn không khai báo X làm thông số loại cho C. Hãy thử các cách sau:

class C[X, M[X] <: A[X]] 
+0

điều này cũng không thực hiện được công việc. Vấn đề là C mong đợi một loại có tham số kiểu. Khi bạn thử C [A] mới, nó sẽ hoạt động, bởi vì A lấy đối số kiểu. – tim

+0

Điều này sẽ không hoạt động - C bây giờ mong đợi hai tham số kiểu. – gpampara

6

Hãy thử cú pháp này.

class C[M <: A[_]] 

Điều này có nghĩa là C là lớp có một tham số kiểu, phải là một phân lớp của A và có một tham số kiểu.

15

Hãy xem ý nghĩa của điều này bằng tiếng Anh đơn giản.

class A[X] 

có nghĩa là: hãy là một lớp có một tham số loại.

class C[M[X] <: A[X]] 

có nghĩa là: hãy C là một lớp mà có một tham số kiểu, mà phải là một lớp mà có một tham số kiểu AND, tham số, là một lớp con của lớp Một tham số với cùng một loại.

Khi bạn viết

new C[A] 

bạn đang nói: tạo một thể hiện của C với A như tham số. A có tuân theo các tiêu chí trên không? Có, đó là một lớp có một tham số kiểu, và tham số hóa nó là một lớp con của chính nó được tham số hóa.

Tuy nhiên, khi bạn viết

new C[A[Int]] 

tham số kiểu bạn đang cố gắng để cung cấp cho C, A [Int], không phù hợp với các tiêu chí: A [Int] không mất bất kỳ thông số chủng loại, mà trình biên dịch vui lòng cho bạn biết. (Và nó cũng không phải là phân lớp của A [X].)

+1

Đây là câu trả lời đúng; điều duy nhất mà tôi sẽ thêm (để hỗ trợ tìm kiếm trên web) là đây là ví dụ về loại có mức độ cao hơn, trong đó tham số loại C được gọi là có loại * -> *. Một [Int] ngược lại chỉ đơn giản là có loại *. –

+0

Ý của bạn là 'A' thay vì 'C'? 'A [Int]' có kiểu '*', nhưng A nên là '* -> *', không? Sau đó 'C' nên là' (* -> *) -> * '? – Emre

0

Bạn không phải lớp học của mình có tham số loại ONE, bạn sẽ không mất hai! Hai giải pháp khả thi:

class A[X] { 
    type T = X 
} 
class C[M <: A[_]] { 
    //use M#T if you want the type T was parameterized with. 
} 

Hoặc, bạn có thể làm:

class A[X] 
class C[T, M[A] <: A[A]] { 
    //when you want the type, write M[T], not M. 
} 

TUY NHIÊN, những gì bạn có thể muốn này là:

class A[X] 
class C[M <: A[_]] 
+0

Để dễ dàng hơn, điều này tương đương với java: lớp A {...} // cho tất cả. lớp C > {...} // trước tiên. không hoàn hảo mặc dù. // giây là không thể. – Anonymous

1

Đó là tất cả giải thích here, tập trung vào "chung Cạm bẫy "phần vì nó là khá TLTR.

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