25

Właśnie w celu wyjaśnienia, kiedy mówię wielokrotnego assigment, przyporządkowanie równoległego, demontażu struktury wiążą Znaczy następujący wzór pasujący gemwielokrotne przypisanie niebędących krotek w Scala

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

który przypisuje "one" do x i 1 do y.

starałem się zrobić

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

się spodziewałem, że scala będzie próbował dopasować wzór tablicy z wzorca i rzucał wyjątek czasu wykonywania, jeśli długość tablicy nie będzie pasować do długości wzoru.

Wszystkie moje próby łatwego przekonwertowania Array na Tuple2 były daremne.

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:_*) 

Czy istnieje jakiś sposób na wykorzystanie wielu zadań z tablicami lub listami?

Odpowiedz

43

Wszystko, co musisz zrobić, to dokonać val bok (na lewo od =) Zgodne z inicjatora (po prawej stronie =):

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 

Jak oczekiwaniami, scala.MatchError zostanie wyrzucony w środowisku uruchomieniowym, jeśli rozmiar tablicy nie jest zgodny (nie ma 3, w powyższym przykładzie).

+9

Działa to, ponieważ obiekt 'Array' zawiera metodę' unapplySeq', dzięki czemu może być używany jako Pattern Exractor. 'Array.unapplySeq (" XXX, YYY, ZZZ ".split (", ")' jest wywoływane, zwracając 'Some (ArrayBuffer (XXX, YYY, ZZZ))', który jest 'Some' i zawiera trzy elementy do połącz z 'x',' y' i 'z'. – retronym

12

Ponieważ twój ciąg może mieć dowolną zawartość, wynik nie może mieć zagwarantowanej formy 2-krotnej przez system typu (i żadna konwersja nie ma sensu). Dlatego będziesz musiał radzić sobie z sekwencji (takich jak tablice).

Na szczęście istnieją right-ignoring sequence patterns, które pozwalają mimo wszystko wygodnie dopasować wartości wyników.

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

Cytując się: "Spodziewałem się, że scala spróbuje dopasować wzór do tablicy z wzorcem, i wyrzuci wyjątek środowiska wykonawczego, jeśli długość tablicy będzie niezgodna z długością wzoru", również Zobacz rozwiązanie Randalla. W każdym razie jest to również fajne. Tak prosty, że chciałbym o tym pomyśleć. +1. –

+0

W Scala 2.8, macierz nie jest już Seq, więc ta technika tam nie działa. –

+1

Technika z pewnością działa, wystarczy napisać "Array" zamiast "Seq". Lub jeśli możesz być chill na koniec String, val Array (x, y) = "ab" split "" wziąć 2 – extempore

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