我对Scala相当新,我想知道下面的代码行是做什么的:
class E{
val (a: A, b: B, c:C, d:D) = {
...
}
}
是否正在进行赋值(因为val?)然后执行正文?
答案 0 :(得分:3)
执行正文,然后解构结果:
val (a: A, b: B, c:C, d:D) = {
...
}
首先,正文产生一些结果(预期是元组*),然后将这个元组分解为元素,每个元素都分配给a
,b
,{{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)
方法处理,如第一个._x
,foo._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