在Scala中声明多个variables

我想用val来声明多个variables像这样:

 val a = 1, b = 2, c = 3 

但无论什么原因,这是一个语法错误,所以我最终使用:

 val a = 1 val b = 2 val c = 3 

要么

 val a = 1; val b = 2; val c = 3; 

我个人觉得这两个选项过于冗长而且有点丑陋。

有更好的select吗?

另外,我知道Scala是非常深思熟虑的语言,那么为什么不是val a = 1, b = 2, c = 3语法是否允许?

微不足道的答案是将它们声明为元组:

 val (a, b, c) = (1, 2, 3) 

这里有趣的是这是基于模式匹配的。 实际发生的是你正在构造一个元组,然后通过模式匹配为abc赋值。

让我们考虑一些其他的模式匹配例子来进一步探索这个问题:

 val DatePattern = """(\d{4})-(\d\d)-(\d\d)""".r val DatePattern(year, month, day) = "2009-12-30" val List(rnd1, rnd2, rnd3) = List.fill(3)(scala.util.Random.nextInt(100)) val head :: tail = List.range(1, 10) object ToInt { def unapply(s: String) = try { Some(s.toInt) } catch { case _ => None } } val DatePattern(ToInt(year), ToInt(month), ToInt(day)) = "2010-01-01" 

正如附注一样,第三个例子特别是可以写得更简单,而没有说明模式匹配,如下所示。

 val rnd1, rnd2, rnd3 = scala.util.Random.nextInt(100) 

Daniel的回答很好地总结了做这件事的正确方法,以及它为什么起作用。 既然他已经涵盖了这个angular度,我会试着回答你更广泛的问题(关于语言devise)…

只要有可能,Scala就会努力避免添加语言特性,而采用现有机制来处理事物。 例如,Scala不包含break语句。 然而,将自己的一个图书馆作为一个图书馆几乎是微不足道的:

 case object BreakException extends RuntimeException def break = throw BreakException def breakable(body: =>Unit) = try { body } catch { case BreakException => () } 

这可以通过以下方式使用:

 breakable { while (true) { if (atTheEnd) { break } // do something normally } } 

注意:这包含在Scala 2.8的标准库中)

像Ruby这样的语言(例如x = 1, y = 2, z = 3 )允许的多个赋值语法属于“冗余语法”的范畴。 当Scala已经有了一个能够启用特定模式的特性时,它就避免了添加一个新特性来处理这种特殊模式的特殊情况。 在这种情况下,Scala已经具有模式匹配(一般特性),可以用来处理多个赋值(通过使用其他答案中概述的元组技巧)。 没有必要以单独的方式来处理这个特殊的情况。

在略有不同的情况下,值得注意的是C的(也就是Java的)多重赋值语法也是另一个更一般特征的特例。 考虑:

 int x = y = z = 1; 

这利用了赋值返回C衍生语言赋值的事实(以及赋值是右联合的)的事实。 斯卡拉情况并非如此。 在斯卡拉,作业返回Unit 。 虽然这确实有一些令人讨厌的缺点,但它在理论上更为有效,因为它直接强调了赋值的副作用性质。

我会在这里添加一个怪癖,因为它打到了我自己并可能帮助别人。

当使用模式匹配时,sa在声明多个variables时,不要使用variables的Capital名称。 它们在模式匹配中被当作类的名字,在这里也适用。

  val (A,B)= (10,20) // won't work println(A) 

错误消息不能真正告诉发生了什么事情:

 src/xxx.scala:6: error: not found: value A val (A,B)= (10,20) ^ src/xxx.scala:6: error: not found: value B val (A,B)= (10,20) ^ src/xxx.scala:7: error: not found: value A println(A) ^ 

我以为` – 舔会解决这个问题,但由于某种原因似乎并不(不知道,为什么不):

  val (`A`,`B`)= (10,20) println(A) 

即使如此,仍然是相同的错误。

请评论,如果你知道如何使用元组初始化模式与大写variables名称。

它似乎工作,如果你在一个元组声明它们

 scala> val (y, z, e) = (1, 2, 45) y: Int = 1 z: Int = 2 e: Int = 45 scala> e res1: Int = 45 

虽然我可能会去个别发言。 对我来说,这看起来更清楚:

 val y = 1 val z = 2 val e = 45 

特别是如果variables是有意义的。

如果你所有的variables是相同的types,并采取相同的初始值,你可以这样做。

 val a, b, c: Int = 0;