簡體   English   中英

將Scala與一組子類型相交

[英]Intersect Scala set with set of subtype

為什么這個函數不能編譯?

case class MyType(n: Int)
def intersection(s1: Set[MyType], s2: Set[_ <: MyType]) =
  (s1 & s2)

我收到以下錯誤:

錯誤:類型不匹配; 找到:設置[_ $ 1]其中類型_ $ 1 <:MyType required:scala.collection.GenSet [MyType]注意:_ $ 1 <:MyType,但是特性GenSet在類型A中是不變的。您可能希望研究一個通配符類型as _ <: MyType (SLS 3.2.10)(w&r)

是否有一種簡單的方法可以“提升”第二個參數來鍵入Set [MyType]而不使用asInstanceOf?

這是因為Set定義為Set[A] 它是變體而不是共變體。

&被定義為

def &(that: GenSet[A]): Set[A]

它期望和類型Set[A] 但是你提供Set[_ <: MyType]

Set[_ <: Mytype]Set[MyType]共變體。 但正如聲明所說,該論證應該是變體的,即Set[MyType] ,因此錯誤。

PS:您可以將協方差視為從窄到寬的類型轉換。 例如:如果Dog延伸Animal ,如果你做Animal a = new Dog() ,你有一只狗(狹窄)轉換為動物(更廣泛)。 期望它不變的類型。 即如果它需要Animal ,你只能提供Animal 另一個例子是java.util.ArrayList ,它是in-variant。

Set在其類型參數上不協變。

所以一個簡單的解決方案是轉換為List (這是協變的):

def intersection(s1: Set[MyType], s2: Set[_ <: MyType]) =
    s1.toList.intersect(s2.toList).toSet

Set是不變的,但是有一個非常簡單的解決方法:

def intersection(s1: Set[MyType], s2: Set[_ <: MyType]) =
  s2 filter s1

或者,如果想要為結果類型獲得更好的類型推斷:

def intersection[X <: MyType](s1: Set[MyType], s2: Set[X]): Set[X] =
  s2 filter s1

這里s1用作函數。 函數在參數中是反變量的,因此s1.apply of type (MyType) => Boolean是可接受的(_ <: MyType) => Boolean

性能是一樣的intersect ,因為this filter that是如何intersect的實現Set

暫無
暫無

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

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