Множественное назначение не кортежей в Scala - PullRequest
29 голосов
/ 04 марта 2010

Просто чтобы уточнить, когда я говорю множественное присвоение, параллельное назначение, деструктурирующее связывание, я имею в виду следующий камень сопоставления с образцом

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

, который присваивает "one" x и 1 y.

Я пытался сделать

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

Я ожидал, что scala попытается сопоставить шаблон с массивом с шаблоном и выдаст исключение времени выполнения, если длина массива не будет соответствовать длине шаблона.

Все мои попытки легко конвертировать Array в Tuple2 были тщетными.

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

Есть ли какой-нибудь удобный способ использовать множественные присваивания с массивами или списками?

Ответы [ 3 ]

46 голосов
/ 04 марта 2010

Все, что вам нужно сделать, это сделать вашу сторону val (слева от =) совместимой с вашим инициализатором (справа от =):

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

Как и ожидалось, scala.MatchError будет выброшено во время выполнения, если размер массива не совпадает (не 3, в приведенном выше примере).

12 голосов
/ 04 марта 2010

Поскольку ваша строка может иметь произвольное содержимое, нельзя гарантировать, что результат будет иметь форму 2-кортежа системой типов (и преобразование не имеет смысла вообще). Поэтому вам все равно придется иметь дело с последовательностями (например, с массивами).

К счастью, есть шаблоны последовательностей, игнорирующие право , которые, тем не менее, позволяют удобно сопоставлять значения результатов.

val Seq(x, y, _ @ _*) = "a b".split(" ")
6 голосов
/ 22 декабря 2010
scala> val Array(x, y, _*) = "a b" split " "
x: java.lang.String = a
y: java.lang.String = b
...