scala中非元组的多重赋值

Posted

技术标签:

【中文标题】scala中非元组的多重赋值【英文标题】:Multiple assignment of non-tuples in scala 【发布时间】:2011-01-23 19:28:24 【问题描述】:

澄清一下,当我说多重赋值、并行赋值、解构绑定时,我指的是以下模式匹配 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:_*)

有没有什么巧妙的方法可以对数组或列表使用多重赋值?

【问题讨论】:

【参考方案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

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

【讨论】:

之所以有效,是因为对象Array 包含unapplySeq 方法,使其可用作提取器模式。调用Array.unapplySeq("XXX,YYY,ZZZ".split(","),返回Some(ArrayBuffer(XXX, YYY, ZZZ)),这是一个Some,并包含三个要绑定到xyz的元素。 为什么val Array(X, Y, Z) = "XXX,YYY,ZZZ".split(",") 不起作用?我得到&lt;console&gt;:14: error: not found: value X... @Batato 匹配变量必须小写【参考方案2】: scala> val Array(x, y, _*) = "a b" 拆分 "" x: java.lang.String = a y: java.lang.String = b

【讨论】:

【参考方案3】:

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

谢天谢地,有right-ignoring sequence patterns 可以让您方便地匹配结果值。

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

【讨论】:

引用我自己的话:“我期待 scala 会尝试将数组与模式匹配,如果数组的长度与模式的长度不匹配,则会抛出运行时异常” ,另见兰德尔的解决方案。无论如何,这也是一个不错的选择。如此简单,我希望我自己考虑一下。 +1。 在 Scala 2.8 中,Array 不再是 Seq,因此该技术在此行不通。 该技术确实有效,您只需编写“Array”而不是“Seq”。或者,如果您对字符串的结尾感到冷漠, val Array(x, y) = "a b" split " " take 2 val Array(x, y, _*) = "a b".split(" ") 也可以减少语法混乱。我不认为_ @ 有用。

以上是关于scala中非元组的多重赋值的主要内容,如果未能解决你的问题,请参考以下文章

来自元组的 JavaScript 变量赋值

是否可以在 Scala 中对变量进行元组赋值? [复制]

元组的常用方法

python列表和元组的方法和属性

Python基础-04元组

Python基础-04元组