2012-04-05 16 views
6

Đưa ra định nghĩa lớp với tham số kiểu ràng buộc Animal[A <: String] có vẻ như trình biên dịch Scala không suy ra B <: String từ Animal[B]. Suy luận có được phép không? Làm thế nào để giúp trình biên dịch để làm suy luận?Làm cách nào để xác định các lớp chữ hoa với các thành viên có tham số kiểu không ràng buộc?

Dưới đây là ví dụ cụ thể với các trường hợp mà thiếu suy luận này là một vấn đề.

Hãy xem xét các hệ thống cấp bậc trường hợp lớp sau đây:

sealed trait Person[+T <: Person[T]] 
case class Student() extends Person[Student] 
case class Professor() extends Person[Professor] 

tôi cần phải xác định một lớp trường hợp University mà tôi có thể nhanh chóng với một biến kiểu Person[_], ví dụ val p: Person[_] = Student(). Tôi nghĩ điều này sẽ làm việc với các định nghĩa sau đây:

case class University(p: Person[_]) 

Nhưng điều này không biên dịch với các lỗi:

type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]] 

Nếu tôi gắn tham số kiểu của lớp trường hợp University nó biên dịch (nó cũng thu thập bằng các thông số không bị chặn nếu tôi bỏ từ khóa case nhưng đây không phải là một tùy chọn trong trường hợp của tôi):

case class BoundUniversity[P <: Person[P]](p: Person[P]) 

Nhưng phiên bản này không được phép instantiated với một biến vô biên của kiểu Person[_]:

val p: Person[_] = Student() 
BoundUniversity(p) 

không biên dịch với:

inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]] 

Các lỗi tương tự xảy ra đối với một phương thức với một đối số ràng buộc như:

def general[P <: Person[P]](p: P) = println(p) 

vì vậy đây là không cụ thể cho các nhà xây dựng lớp.

Hai câu hỏi:

  1. Loại Person được định nghĩa với giới hạn tham số Person[+T <: Person[T]], do đó mỗi trường hợp thuộc loại này được bảo hiểm phải tôn trọng những giới hạn: val p: Person[P] ngụ ý rằng P <: Person[P]; hoặc tôi đang thiếu một cái gì đó? Vì vậy, làm thế nào tôi có thể làm cho điều này rõ ràng để trình biên dịch để nó không phàn nàn?

  2. Làm cách nào/Tôi có thể xác định lớp chữ hoa với các thành viên có thông số loại không ràng buộc như case class University(p: Person[_]) không?

+0

Có 'T' cần phải được so sánh? – leedm777

+0

@dave trong trường hợp cụ thể của tôi 'T' cần phải được biến đổi, nhưng tôi nghĩ rằng điều này không thay đổi vấn đề: xem ví dụ giới thiệu. –

+0

Bạn có thể đến một nơi nào đó bằng cách sử dụng [loại trừu tượng] (http://docs.scala-lang.org/tutorials/tour/abstract-types.html), nhưng sau đó chúng trở thành [khá nhiều bất biến] (http: // stackoverflow). com/a/5359015/115478). – leedm777

Trả lời

2

Một loại X[_] hầu như không bao giờ bạn muốn. Khi bạn sử dụng _ trên một loại, bạn về cơ bản nói rằng bạn không quan tâm tham số đó là gì, bởi vì bạn sẽ không bao giờ cần phải sử dụng nó.

Dù sao, bản dịch này cũng được biên dịch. Nó cũng có thể cắn bạn xuống đường, các loại tồn tại là những thứ khó khăn mà họ đang có, nhưng ...

case class University(p: Person[t] forSome { type t <: Person[t] }) 
+0

Loại hiện hữu tốt đẹp, cảm ơn! Điều này biên dịch, nhưng không thể được khởi tạo với 'val p: Person [_] = Student(); Đại học (p) '. Kiểu 'Person [_]' mà tôi đã đề cập đến từ một danh sách: 'List [Person [_]] (Student(), Professor())'. Lưu ý rằng 'List (Student(), Professor())' không biên dịch. Tôi cảm thấy có một mô hình ở đây nhưng tôi không thể đặt ngón tay trên nó ... –

+0

Thực ra điều này không hiển thị lỗi trong Eclipse của tôi nhưng không biên dịch với 'scalac'. Loại mismtach, tìm thấy 'Person [(một số khác) _1 (trong phương thức equals)] trong đó type (một số khác) _1 (trong phương thức bằng) <: schemdesc.hierarchy.eval.Person [_0]', bắt buộc 'Person [_ < : schemdesc.hierarchy.eval.Person [_0]] ' –

+0

@jullybobble Biên dịch dòng trên - tôi đã thử nghiệm nó. Nếu bạn có một vấn đề biên dịch, bạn đang làm một cái gì đó khác nhau. Và bạn không thể sử dụng 'Person [_]' - nó sẽ không hoạt động. Bạn phải sử dụng loại tồn tại ở trên nếu bạn muốn nó hoạt động. –