不确定这个Scala语法正在做什么

时间:2014-05-26 01:59:21

标签: scala

我对Scala相当新,我想知道下面的代码行是做什么的:

class E{
  val (a: A, b: B, c:C, d:D) = {
    ...
  }
}

是否正在进行赋值(因为val?)然后执行正文?

3 个答案:

答案 0 :(得分:3)

执行正文,然后解构结果

val (a: A, b: B, c:C, d:D) = {
    ...
}

首先,正文产生一些结果(预期是元组*),然后将这个元组分解为元素,每个元素都分配给ab,{{1}分别和c

您可能已经在Java中看到过这段代码:

d

甚至是python中的这段代码:

int x = 1, y = 2, z = 4;
// now x is 1, y is 2, z is 4

Scala通过一个名为解构赋值的功能将其提升到了新的水平,虽然它不允许使用Java和Python语法,但它更灵活,因为它不仅可以让您获得类似的体验(通过使用元组):

>>> x, y = 1, 2
>>> x
1
>>> y
2

但也是模式匹配的这种用例的概括和extensible concept,例如在数组上:

val (x, y) = (1, 2)

列表:

val xs = Array(1,2,3,4)
val Array(first, second, _*) = xs  // _* mean I don't care about the rest of elements
// first: Int = 1
// second: Int = 2

在许多其他情况下。

您可能认为此操作会以某种方式破坏原始值,但通常不会(除非自定义提取器功能具有副作用)

* tuple有点像已知有限大小的不可变集合,它的每个元素都可以直接用val head::tail = List(1,2,3,4) head: Int = 1 tail: List[Int] = List(2, 3, 4) 方法处理,如第一个._xfoo._1第二个。 scala中的元组具有语法糖 - 大括号。

答案 1 :(得分:2)

val定义了一个无法重新分配的变量。然后(a, b, ..)符号公开一个元组,其值为a,b,...将被分配。

以下是您可以运行的示例:

// define types
type A = String
type B = String
type C = String
type D = String

// adding tuple@ to show a,b,c,d are components of a tuple aka extraction
val tuple@(a: A, b: B, c:C, d:D) = {
  ("aString", "bString", "cString", "dString")
}

println(tuple)

此外,您可以更明确地指定类型,例如

val tuple@(a: A, b: B, c:C, d:D): (A, B, C, D) = {
  ("aString": A, "bString": B, "cString": C, "dString": D)
}

输出是:

defined type alias A
defined type alias B
defined type alias C
defined type alias D
tuple: (A, B, C, D) = (aString,bString,cString,dString)
a: A = aString
b: B = bString
c: C = cString
d: D = dString
(aString,bString,cString,dString)

答案 2 :(得分:2)

您可以运行scala -Xprint:parser -e "val (a, b) = (1, 2)"来解散代码。实际发生的是:

val x$1 = (1, 2) match {
  case Tuple2((a @ _), (b @ _)) => Tuple2(a, b)
}
val a = x$1._1
val b = x$1._2