Beitrag 2015. Damit die Antwort von Tom Crockett klarer wird , hier ein echtes Beispiel.
Zuerst war ich verwirrt. Weil ich aus Python komme, wo du es einfach machen kannst tuple(list(1,2,3))
.
Fehlt es an Scala-Sprache? (Die Antwort lautet: Es geht nicht um Scala oder Python, es geht um statischen und dynamischen Typ.)
Das bringt mich dazu, den Kern zu finden, warum Scala das nicht kann.
Das folgende Codebeispiel implementiert eine toTuple
Methode, die typsicher toTupleN
und typsicher ist toTuple
.
Die toTuple
Methode ruft die Informationen zur Typlänge zur Laufzeit ab, dh keine Informationen zur Typlänge zur Kompilierungszeit, sodass der Rückgabetyp Product
dem des Pythons sehr ähnlich ist tuple
(kein Typ an jeder Position und keine Länge der Typen).
Auf diese Weise kommt es zu Laufzeitfehlern wie Typinkongruenz oder IndexOutOfBoundException
. (Pythons praktisches List-to-Tupel ist also kein kostenloses Mittagessen.)
Im Gegensatz dazu ist es die vom Benutzer bereitgestellte Längeninformation, die die toTupleN
Kompilierungszeit sicher macht.
implicit class EnrichedWithToTuple[A](elements: Seq[A]) {
def toTuple: Product = elements.length match {
case 2 => toTuple2
case 3 => toTuple3
}
def toTuple2 = elements match {case Seq(a, b) => (a, b) }
def toTuple3 = elements match {case Seq(a, b, c) => (a, b, c) }
}
val product = List(1, 2, 3).toTuple
product.productElement(5) //runtime IndexOutOfBoundException, Bad !
val tuple = List(1, 2, 3).toTuple3
tuple._5 //compiler error, Good!
def toTuple(x: List[Int]): R
, was sollte die Art der R?