开发者

Multiple assignment of non-tuples in scala

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 ap开发者_开发问答ply: (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?


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).


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(" ")


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜