问题
Just to clarify, when I say multiple assigment, parallel assignment, destructuring bind I mean the following pattern matching gem
scala> val (x,y) = Tuple2("one",1)
x: java.lang.String = one
y: Int = 1
which assigns "one"
to x
and 1
to y
.
I was trying to do
val (x,y) = "a b".split()
I was expecting that scala would attempt to pattern match the array with the pattern, and would throw a runtime exception if the length of the array wouldn't match the length of the pattern.
All my attempts to easily convert an Array
to a Tuple2
were futile.
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:_*)
Is there any neat way to use multiple assignment with arrays or lists?
回答1:
All you need to do is make your val side (left of the =
) compatible with your initializer (right of the =
):
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
As you expected, a scala.MatchError
will be thrown at runtime if the array size don't match (isn't 3, in the above example).
回答2:
Since your string can have arbitrary contents, the result cannot be guaranteed to have a 2-tuple-form by the type-system (and no conversion would make sense at all). Therefore you'll have to deal with sequences (like arrays) anyway.
Thankfully there are right-ignoring sequence patterns which allow you to match the result values conveniently nevertheless.
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
来源:https://stackoverflow.com/questions/2381666/multiple-assignment-of-non-tuples-in-scala