Подтвердить что ты не робот

Несколько присвоений не-кортежей в scala

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

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

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

4b9b3361

Ответ 1

Все, что вам нужно сделать, это сделать вашу сторону 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

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

Ответ 2

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

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

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

Ответ 3

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