簡體   English   中英

將通用通配符從Java轉換為Scala

[英]Translating generic wildcards from Java to Scala

java.util.Collections類中,我們有兩種sort方法的變體,一種是使用相應的Comparator獲取任意對象的列表:

public static <T> void sort(List<T> list, Comparator<? super T> comparator)

並且獲取可Comparable對象列表:

public static <T extends Comparable<? super T>> void sort(List<T> list)

我在想如何用有界通配符將這種方法簽名翻譯成Scala。 對於第一個版本,我從字面上翻譯了簽名,一眼就沒有編譯問題:

def sort[T](list: List[T], comparator: Comparator[_ >: T]) { ??? }

但后來我發現我無法使用以下參數調用此方法:

val comparator = new Comparator[Object] {
    def compare(o1: Object, o2: Object) = ???
}
val list = new ArrayList[Number]
sort[Object](list, comparator)

最后一行給出了這個編譯錯誤,即使我明確地將類型T指定為Object

類型不匹配; found:java.util.ArrayList [Number] required:java.util.List [Object]注意:Number <:Object,但Java定義的特征List在類型E中是不變的。您可能希望調查通配符類型,例如_ <: Object (SLS 3.2.10)

實際上,我發現甚至不可能直接調用唯一的Java方法,因為它失敗並且具有相同類型的錯誤。

Collections.sort[Object](list, comparator)

至於具有可比列表的版本,我想出了這個聲明:

def sort[T <: Comparable[_ >: T]](list: List[T]) { ??? }

但這根本不起作用:

涉及T類的非法循環引用


我究竟做錯了什么? Scala變體泛型是否遵循Java規則的不同規則? 如何調用一個調用Collections.sort方法而不實際得到編譯錯誤?

邊注:

不,我真的不知道如何在Scala中對列表進行排序。 我知道Scala有自己的一組集合,排序函數和一種比較對象的不同方法(例如OrderedOrdering traits)。 我的問題涉及泛型方法的一般問題以及從Java到Scala的泛型的翻譯。

您為T提供了錯誤的類型參數:您對List[Number]排序,而不是List[Object]

sort[Number](list, comparator)

將工作。

如果要在沒有類型參數的情況下調用sort,則需要定義兩個參數列表(因為類型推斷在Scala中的工作方式):

def sort[T](list: List[T])(comparator: Comparator[_ >: T]) { ??? }

// Then
sort(list)(comparator)

您可能需要考慮使用對協方差有適當支持的Scala類型(即在Scala中, List[Number]List[Object] )。

關於具有可比性的版本,您必須顯式編寫通配符:

def sort[T <: Comparable[T], U <: T](list: List[U]) { ??? }

您可以使用以下命令調用Java變體(或您的變體):

Collections.sort[Number](list, comparator)

這里的問題是因為Java泛型類型是不變的。 換句話說,這在Java中失敗了:

List<Number> l1;
List<Integer> l2 = l1; //contravariance fails
List<Object> l3 = l1; //covariance fails

在Scala中,泛型類型參數可以在聲明中聲明為協變或逆變。 Scala的List類型參數被聲明為協變(這是有效的,因為它是不可變的)。 換句話說,這是有效的:

val l1: List[Number] = ???
val l2: List[Object] = l1 //valid

但是因為你使用Java的java.util.List不是一個選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM