2010-09-15 24 views
12

Tôi đã có một đặc điểm mà trông như thế này (một số thông tin có thể được tìm thấy tại this related question by myself mặc dù tôi không nghĩ rằng, nó cần thiết cho câu hỏi này)hiệp biến Typeparameter trong scala cần được bất biến trong giao diện java

trait Extractor[-A,+B] { 
    def extract(d:A):B 
    //lots of other things 
} 

Để sử dụng tính năng này trong khung công tác java hiện tại, tôi muốn Extractor này có chức năng trả về Comparator[B] (là java.util.Comparator) hoặc thậm chí mở rộng hơn Comparator[A]. Bây giờ đặt ra một vấn đề bởi vì tham số loại Comparator s phải là bất biến, trong khi A là contravariant và B là biến thể.

Vì vậy, tôi nhận được lỗi như thế này:

scala> import java.util.Comparator 
import java.util.Comparator 

scala> trait Extractor[-A,+B] extends Comparator[A] 
<console>:6: error: contravariant type A occurs in invariant position in type [-A,+B]java.lang.Object with java.util.Comparator[A] of trait Extractor 
     trait Extractor[-A,+B] extends Comparator[A] 
      ^


scala> trait Extractor[-A, +B] {     
    | def comp:Comparator[B] 
    | } 
<console>:7: error: covariant type B occurs in invariant position in type => java.util.Comparator[B] of method comp 
     def comp:Comparator[B] 
      ^

Bạn có thấy bất kỳ cách nào trong số này hoặc là này chỉ là một trong những trường hợp "sử dụng Generics java trong scala đau"?

Trả lời

12

Với sự giúp đỡ của kiểu giới hạn nó có thể làm như sau:

scala> trait Extractor[-A, +B] { 
    | def comp:Comparator[_ <: B] 
    | } 
defined trait Extractor 
+0

cảm ơn. Điều đó hoạt động. Mã chưa chạy nhưng mã của bạn và khai báo hiệu quả của trình So sánh biên dịch lưu và âm thanh. Cảm ơn bạn rất nhiều. – Agl

+0

Tôi biết đây là một câu hỏi hoàn toàn khác nhưng có một bài viết/hướng dẫn/blog tốt bao gồm các loại giới hạn và các biến thể không? Tôi đã đọc về nó nhưng người ta có thể tranh luận rằng tôi đã không học quá nhiều từ họ;) (mặt khác, có lẽ đó chỉ là tôi. Vì vậy, tất cả đọc tất cả một lần nữa) – Agl

+2

Điều này là khá tốt (mặc dù nó không lên -to-date - không có thông tin về một số tính năng 2.8): http://programming-scala.labs.oreilly.com/ch12.html –

7

Bạn có thể làm Extractor[A,B] mở rộng Comparator[A] bằng @uncheckedVariance chú thích.

scala> import scala.annotation.unchecked.uncheckedVariance 
import scala.annotation.unchecked.uncheckedVariance 

scala> trait Extractor[-A,+B] extends java.util.Comparator[A @uncheckedVariance] 
defined trait Extractor 

@uncheckedVariance là an toàn ở đây vì Comparator có thể đã được định nghĩa là Comparator[-T]. Có một số discussion xung quanh việc thực hiện Ordering biến đối với Scala 2.8 bằng cách sử dụng chú thích này.

Chỉnh sửa Xem this question để biết thêm về @uncheckedVariance.

+0

uh đó là một tốt đẹp quá. Trên thực tế, đây có thể là phiên bản kết thúc trong mã của tôi. . . ngay sau khi tôi tìm thấy thời gian để đọc chủ đề mà bạn đã đăng. Cảm ơn rất nhiều! – Agl

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