Scala bug或功能?带大写字母变量的多重赋值错误

时间:2016-04-02 00:57:48

标签: scala mass-assignment

假设函数r返回五个值的元组。

scala> def r = (1,2,3,4,5)
r: (Int, Int, Int, Int, Int)

当我从r分配返回的值时,我得到了大写字母变量的错误。

scala> val (a,b,c,d,E) = r
<console>:13: error: not found: value E
       val (a,b,c,d,E) = r
                    ^

如果我不使用大写字母,则不会发生错误。

scala> val (a,b,c,d,e) = r
a: Int = 1
b: Int = 2
c: Int = 3
d: Int = 4
e: Int = 5

但是,我可以用单一的assignemnt分配大写字母变量。

scala> val Q = 10
Q: Int = 10

这是Scala的错误或功能吗?

2 个答案:

答案 0 :(得分:5)

这是一个特色......虽然不是很理想。

执行val (a,b,c) = tuple时,实际上是模式匹配:

tuple match {
   case (a,b,c) => ...
}

现在,上面的语句使用unapply从元组中提取三个值,并将它们分配给a,b和c。但是这个:

tuple match {
   case (1, 2, 3) => ...
}

有什么不同的东西。它从元组中提取三个值,并将它们与左侧的三个值进行比较。如果你想匹配变量怎么办:

val foo = 1
val bar = 2
val bat = 3

tuple match {
  case(foo, bar, bat) => ...
}

这不起作用:这种情况与第一种情况完全相同,并且将完全相同:它将元组中的值提取为三个(新的)局部变量而不进行任何匹配。但是如果你想匹配变量怎么办?怎么解决这个问题?有两种方法:您可以将变量名称括在反引号中,或者使名称以字母开头:

  val Foo = 1
  val bar = 2
  var baz = 3

  tuple match { 
    case(Foo, `bar`, `bat`) => ...
  }

总结:tuple match { case (foo, _) =>表示&#34;从元组中提取第一个元素并分配给新变量footuple match { case (Foo, _)表示&#34;如果元组的第一个元素等于现有变量case&#34;的值,则执行此Foo。 &#34;分配与#34;遵循相同的逻辑(因为它们不是真的&#34;赋值&#34;只是模式匹配的另一种语法),所以,当你说val (a,b,c,d,E) = r时,它意味着&#34;赋值r到新变量的前四个元素,并将最后一个元素与现有变量E&#34;相匹配。但是E不存在,因此错误。

答案 1 :(得分:3)

称为稳定标识符。因此,每当您在执行模式匹配(在这种情况下发生)时使用大写字母作为变量名称(或在变量名称的开头),编译器认为这是一个常量值,因此转到行为(比较两个值E和5而不是将5分配给E)。

示例:

val (a,b,c,d,extsom) = r这会有用。

val (a,b,c,d,Extsom) = r这不会。