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

pro*_*eek 4 scala mass-assignment

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

scala> def r = (1,2,3,4,5)
r: (Int, Int, Int, Int, Int)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

但是,我可以用单个assignemnt分配大写字母变量.

scala> val Q = 10
Q: Int = 10
Run Code Online (Sandbox Code Playgroud)

这是Scala的错误或功能吗?

Dim*_*ima 5

这是一个特色......尽管不是很理想.

当你这样做时val (a,b,c) = tuple,它实际上是一个模式匹配:

tuple match {
   case (a,b,c) => ...
}
Run Code Online (Sandbox Code Playgroud)

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

tuple match {
   case (1, 2, 3) => ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

tuple match {
  case(foo, bar, bat) => ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

  tuple match { 
    case(Foo, `bar`, `bat`) => ...
  }
Run Code Online (Sandbox Code Playgroud)

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