在scala中多次分配非元组

Ela*_*ich 31 arrays functional-programming scala pattern-matching variable-assignment

只是为了澄清,当我说多个分配,并行分配,解构绑定我的意思是以下模式匹配宝石

scala> val (x,y) = Tuple2("one",1)
x: java.lang.String = one
y: Int = 1
Run Code Online (Sandbox Code Playgroud)

其分配"one"x1y.

我试图做

val (x,y) = "a b".split()
Run Code Online (Sandbox Code Playgroud)

我期望scala会尝试将模式与模式进行模式匹配,如果数组的长度与模式的长度不匹配,则会抛出运行时异常.

我所有试图轻松转换Array为a的尝试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:_*)
Run Code Online (Sandbox Code Playgroud)

有没有任何巧妙的方法来使用数组或列表的多个赋值?

Ran*_*ulz 49

您需要做的就是使您的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
Run Code Online (Sandbox Code Playgroud)

如您所料,scala.MatchError如果数组大小不匹配,则会在运行时抛出(在上例中不是3).

  • 这是因为对象`Array`包含`unapplySeq`方法,使其可用作Exractor Pattern.`Array.unapplySeq("XXX,YYY,ZZZ".split(",")`被调用,返回`Some(ArrayBuffer(XXX,YYY,ZZZ))`,这是一个`Some`,并包含三个元素绑定到`x`,`y`和`z`. (9认同)

Dar*_*rio 12

由于您的字符串可以包含任意内容,因此不能保证结果类型系统具有2元组形式(并且根本没有转换是有意义的).因此,无论如何,你必须处理序列(如数组).

值得庆幸的是,有一些忽略序列模式,可以方便地匹配结果值.

val Seq(x, y, _ @ _*) = "a b".split(" ")
Run Code Online (Sandbox Code Playgroud)


Jim*_*ter 9

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