Scala 错误或功能?大写字母变量的多重赋值错误
Scala bug or feature? Multiple assignment error with capital letter variables
假设函数 r
returns 包含五个值的元组。
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
但是,我可以用单个赋值给大写字母变量赋值。
scala> val Q = 10
Q: Int = 10
这是 Scala 的错误或功能吗?
这是一个功能......虽然不是很理想。
当你做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, _) =>
表示 "extract the first element from tuple and assign to a new variable foo
. tuple match { case (Foo, _)
means " 如果元组的第一个元素等于 现有 的值,则执行此 case
变量 Foo
”。
"Assignments" 遵循相同的逻辑(因为它们实际上并不是 "assignments" 而是模式匹配的另一种语法),因此,当您说 val (a,b,c,d,E) = r
时,它的意思是 "assign the first four elements of r
to the new variables, and match the last element against existing variable E
" .但是 E
不存在,因此出现错误。
它叫做稳定标识符。因此,每当您在进行模式匹配(在这种情况下发生)时使用大写字母作为变量名(或在变量名的开头)时,编译器认为这是一个常量值,因此会出现行为(比较两个值 E 和 5,而不是将 5 分配给 E)。
示例:
val (a,b,c,d,extsom) = r
这行得通。
val (a,b,c,d,Extsom) = r
这个不会。
假设函数 r
returns 包含五个值的元组。
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
但是,我可以用单个赋值给大写字母变量赋值。
scala> val Q = 10
Q: Int = 10
这是 Scala 的错误或功能吗?
这是一个功能......虽然不是很理想。
当你做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, _) =>
表示 "extract the first element from tuple and assign to a new variable foo
. tuple match { case (Foo, _)
means " 如果元组的第一个元素等于 现有 的值,则执行此 case
变量 Foo
”。
"Assignments" 遵循相同的逻辑(因为它们实际上并不是 "assignments" 而是模式匹配的另一种语法),因此,当您说 val (a,b,c,d,E) = r
时,它的意思是 "assign the first four elements of r
to the new variables, and match the last element against existing variable E
" .但是 E
不存在,因此出现错误。
它叫做稳定标识符。因此,每当您在进行模式匹配(在这种情况下发生)时使用大写字母作为变量名(或在变量名的开头)时,编译器认为这是一个常量值,因此会出现行为(比较两个值 E 和 5,而不是将 5 分配给 E)。
示例:
val (a,b,c,d,extsom) = r
这行得通。
val (a,b,c,d,Extsom) = r
这个不会。