なぜScalaの不変の設定は、そのタイプには共変ではないですか?
-
21-08-2019 - |
質問
編集:再書かれたオリジナルの回答に基づいて、この質問には、
scala.collection.immutable.Set
クラスは、その型パラメータには共変ではありません。どうしてこれなの?
import scala.collection.immutable._
def foo(s: Set[CharSequence]): Unit = {
println(s)
}
def bar(): Unit = {
val s: Set[String] = Set("Hello", "World");
foo(s); //DOES NOT COMPILE, regardless of whether type is declared
//explicitly in the val s declaration
}
解決
Set
がための機能として、セットのコンセプトで、その型パラメータで不変です。以下の署名は少し物事を明確にする必要があります:
trait Set[A] extends (A=>Boolean) {
def apply(e: A): Boolean
}
Set
がA
に共変だったら、apply
方法が原因の機能のcontravarianceに型A
のパラメータを取ることができないであろう。 Set
は、潜在的にA
にの反変のかもしれないが、あなたはこのようなことをしたいとき、これはあまりにも問題が発生します:
def elements: Iterable[A]
要するに、最善の解決策でも不変のデータ構造のため、不変のものを維持することです。あなたはimmutable.Map
は、その型パラメータの一つでも不変であることがわかります。
他のヒント
http://www.scala-lang.org/node/9764 のマーティン・オーダーズキーでは書いています:
「のセットの問題について、私は非分散が実装からも茎と信じています。一般的なセットは、キータイプの非変異体配列であるハッシュテーブルとして実装されている。私はそれは少し迷惑な不規則だ同意します。」
だから、それはこのための原則的な理由を構築するための努力のすべてが見当違いだったようです: - )
編集:I(質問者)は、質問を変更したため、この答えは少しオフトピックと思われる理由を疑問に思う人のために、これはあります。
Scalaの型推論は、あなたには、いくつかの状況でCharSequencesはなく文字列を望んでいることを把握するのに十分な良いです。具体的には、2.7.3での私のために、次の作品ます:
import scala.collections.immutable._
def findCharSequences(): Set[CharSequence] = Set("Hello", "World")
直接immutable.HashSetsを作成する方法については:ありません。実装最適化として、以下の5つの要素のimmutable.HashSetsは実際immutable.HashSetのインスタンスではありません。彼らはEmptySet、セット1、SET2、SET3、またはSET4のどちらかです。これらのクラスはimmutable.Setをサブクラス化ではなく、immutable.HashSetます。