Frage

Bearbeiten : Re-geschrieben, diese Frage anhand von Original-Antwort

Die scala.collection.immutable.Set Klasse ist in seiner Art Parameter 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
}
War es hilfreich?

Lösung

Set ist unveränderlich in seiner Art Parameter, weil das Konzept hinter Sätze als Funktionen. Die folgenden Signaturen sollten die Dinge klären leicht:

trait Set[A] extends (A=>Boolean) {
  def apply(e: A): Boolean
}

Wenn Set in A kovariant wurden, wären die apply Verfahren nicht in der Lage einen Parameter vom Typ A nimmt aufgrund der Kontra von Funktionen. Set könnte möglicherweise sein kontra in A, aber auch dies verursacht Probleme, wenn Sie solche Dinge tun:

def elements: Iterable[A]

Kurz gesagt, die beste Lösung ist, die Dinge unveränderlich zu halten, auch für die unveränderliche Datenstruktur. Sie werden feststellen, dass immutable.Map bemerken in einem seiner Art Parameter auch unveränderlich ist.

Andere Tipps

http://www.scala-lang.org/node/9764 Martin Odersky schreibt:

  

„In der Frage der Sätze, ich die Nicht-Varianz ergibt sich auch aus den Implementierungen glauben. Sind häufig Sätze wie Hash-Tabellen implementiert, die nicht-Variante Arrays der Schlüsseltyp sind. Ich bin damit einverstanden, es ist ein wenig ärgerlich Unregelmäßigkeit.“

So scheint es, dass alle unsere Bemühungen, einen prinzip Grund dafür waren fehlgeleitet zu konstruieren: -)

Bearbeiten : für fragen, jemand, warum diese Antwort ein wenig vom Thema scheint, ist dies, weil ich (der Fragesteller) die Frage geändert haben.

Scala Typinferenz ist gut genug, um herauszufinden, dass Sie CharSequences und nicht Strings in einigen Situationen wollen. Insbesondere die folgenden Werke für mich in 2.7.3:

import scala.collections.immutable._
def findCharSequences(): Set[CharSequence] = Set("Hello", "World")

Wie, wie immutable.HashSets direkt zu erstellen: dies nicht tun. Als umsetzungs Optimierung, immutable.HashSets von weniger als 5 Elemente sind nicht wirklich Instanzen immutable.HashSet. Sie sind entweder emptyset, Set1, Set2, Set3 oder Set4. Diese Klassen Unterklasse immutable.Set, aber nicht immutable.HashSet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top