BEARBEITEN : Diese Frage wurde basierend auf der ursprünglichen Antwort neu geschrieben
Die scala.collection.immutable.Set
Klasse ist in ihrem Typparameter nicht kovariant. Warum ist das?
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
}
scala
set
covariance
scala-collections
oxbow_lakes
quelle
quelle
foo(s.toSet[CharSequence])
kompiliert. DietoSet
Methode ist O (1) - sie wird nur umbrochenasInstanceOf
.foo(Set("Hello", "World"))
auch auf 2.10 kompiliert wird, da Scala in der Lage zu sein scheint, den richtigen Set-Typ abzuleiten. Es funktioniert jedoch nicht mit impliziten Konvertierungen ( stackoverflow.com/questions/23274033/… ).Antworten:
Set
ist in seinem Typparameter aufgrund des Konzepts hinter Mengen als Funktionen unveränderlich. Die folgenden Unterschriften sollten die Dinge etwas klarer machen:Wenn dies
Set
kovariant wäreA
, könnte dieapply
MethodeA
aufgrund der Kontravarianz der Funktionen keinen Parameter vom Typ annehmen.Set
könnte möglicherweise kontra inA
, aber auch dies verursacht Probleme , wenn Sie solche Dinge zu tun:Kurz gesagt, die beste Lösung besteht darin, die Dinge auch für die unveränderliche Datenstruktur unveränderlich zu halten. Sie werden feststellen, dass dies
immutable.Map
auch in einem seiner Typparameter unveränderlich ist.quelle
List(1,2,3).contains _
is ist(Any) => Boolean
, während der TypSet(1,2,3).contains _
is istres1: (Int) => Boolean
.unter http://www.scala-lang.org/node/9764 schreibt Martin Odersky:
Es scheint also, dass alle unsere Bemühungen, einen prinzipiellen Grund dafür zu konstruieren, fehlgeleitet waren :-)
quelle
Seq
kovariant ... fehlt mir etwas?Array[Any]
internes Speichern gelöst werden .BEARBEITEN : Für alle, die sich fragen, warum diese Antwort etwas vom Thema abweicht, liegt dies daran, dass ich (der Fragesteller) die Frage geändert habe.
Die Typinferenz von Scala ist gut genug, um herauszufinden, dass Sie in bestimmten Situationen CharSequences und nicht Strings möchten. Insbesondere funktioniert in 2.7.3 Folgendes für mich:
Wie man unveränderliche.HashSets direkt erstellt: nicht. Als Implementierungsoptimierung sind unveränderliche HashSets mit weniger als 5 Elementen keine Instanzen von unveränderlichem HashSet. Sie sind entweder EmptySet, Set1, Set2, Set3 oder Set4. Diese Klassen sind unveränderlich. Set, aber nicht unveränderlich. HashSet.
quelle