25

Solo para aclarar, cuando digo assigment múltiple, misiones paralelo, desestructuración bind quiero decir el siguiente patrón de la gema a juegoasignación múltiple de los no-tuplas en Scala

scala> val (x,y) = Tuple2("one",1) 
x: java.lang.String = one 
y: Int = 1 

que asigna "one"-x y 1-y.

yo estaba tratando de hacer

val (x,y) = "a b".split() 

que estaba esperando que Scala intentaría patrón que coincida con la matriz con el patrón, y sería una excepción de tiempo de ejecución si la longitud de la matriz no se correspondería con la longitud del patrón.

Todos mis intentos de convertir fácilmente un Array en un Tuple2 fueron en vano.

scala> Tuple2(Array(1,2):_*) 
<console>:7: error: wrong number of arguments for method apply: (T1,T2)(T1, T2) 
in object Tuple2 
     Tuple2(Array(1,2):_*) 
    ^

scala> Tuple2(Array(1,2).toList:_*) 
<console>:7: error: wrong number of arguments for method apply: (T1,T2)(T1, T2) 
in object Tuple2 
     Tuple2(Array(1,2).toList:_*) 

¿Hay alguna manera ordenada de usar la asignación múltiple con matrices o listas?

Respuesta

43

Todo lo que necesita hacer es realizar su lado val (a la izquierda de la =) compatible con el inicializador (derecha de la =):

scala> val Array(x, y, z) = "XXX,YYY,ZZZ".split(",") 
x: java.lang.String = XXX 
y: java.lang.String = YYY 
z: java.lang.String = ZZZ 

como se esperaba, se lanzará una scala.MatchError en tiempo de ejecución si el tamaño de la matriz no coincide (no es 3, en el ejemplo anterior).

+9

Esto funciona porque el objeto 'Array' incluye el método' unapplySeq', lo que lo hace utilizable como un Patrón Exractor. 'Array.unapplySeq (se llama a" XXX, YYY, ZZZ ".split (", ")', devolviendo 'Some (ArrayBuffer (XXX, YYY, ZZZ))', que es 'Some', y contiene tres elementos para enlazar a 'x',' y', y 'z'. – retronym

12

Dado que su cadena puede tener contenidos arbitrarios, el sistema de tipos no puede garantizar que el resultado tenga una forma de 2 tuplas (y ninguna conversión tendría sentido en absoluto). Por lo tanto, tendrá que ocuparse de secuencias (como matrices) de todos modos.

Afortunadamente hay right-ignoring sequence patterns que le permiten hacer coincidir los valores de los resultados convenientemente sin embargo.

val Seq(x, y, _ @ _*) = "a b".split(" ") 
+0

Citando a mí mismo: "Yo estaba esperando que Scala intentaría patrón que coincida con la matriz con el patrón, y sería una excepción de tiempo de ejecución si la longitud de la matriz no se correspondería con la longitud del patrón", también ver la solución de Randall. De todos modos, esta es una buena también. Tan simple que desearía haberlo pensado yo mismo. +1. –

+0

En Scala 2.8, Array ya no es Seq, por lo que esta técnica no funciona allí. –

+1

La técnica ciertamente funciona, solo escribe "Array" en lugar de "Seq". O si puede relajarse al final de String, val Array (x, y) = "ab" split "" tomar 2 – extempore

6
 
scala> val Array(x, y, _*) = "a b" split " " 
x: java.lang.String = a 
y: java.lang.String = b 
Cuestiones relacionadas