多变量赋值
如果需要以简便的方式对多变量赋值,比如:
var MONTH = 12; var DAY = 24
var (HOUR, MINUTE, SECOND) = (12, 0, 0)
但是结果并不符合预期:
MONTH: Int = 12
DAY: Int = 24
<console>:11: error: not found: value HOUR
var (HOUR, MINUTE, SECOND) = (12, 0, 0)
^
<console>:11: error: not found: value MINUTE
var (HOUR, MINUTE, SECOND) = (12, 0, 0)
^
<console>:11: error: not found: value SECOND
var (HOUR, MINUTE, SECOND) = (12, 0, 0)
^
Scala 允许使用大写字母作为普通的变量名,就和 MONTH、DAY 一样并没有报错。但是第二条语句中使用的多变量赋值方式却不同。
因为多变量赋值实质上基于模式匹配,但是在模式匹配中,以大写字母开头的变量代表着特殊的意义:它们是稳定标示符。
稳定标识符是给常量预留的,比如:
final val TheAnswer = 42
def checkGuess(guess: Int) = guess match {
case TheAnswer => "Your guess is correct"
case _ => "Try again"
}
scala> checkGuess(21) // res8: String = Try again
scala> checkGuess(42) // res9: String = Your guess is correct
相反,小写的变量名定义为变量模式,表示对变量的赋值:
var (hour, minute, second) = (12, 0, 0)
// hour: Int = 12 minute: Int = 0 second: Int = 0
因此在一开始的例子中,并不是对变量的赋值,而是对常量的匹配。
总结
如果想要使用大写的变量名,在极端的情况下,会对当前作用域中的值进行匹配,这个模式匹配会编译成功,并且最终的结果依赖于值是否真正匹配:
val HOUR = 12; val MINUTE, SECOND = 0;
scala> var (HOUR, MINUTE, SECOND) = (12, 0, 0) // 1 - 匹配成功
val HOUR = 13; val MINUTE, SECOND = 0;
scala> var (HOUR, MINUTE, SECOND) = (12, 0, 0) // 2 - 匹配失败
scala.MatchError: (12,0,0) (of class scala.Tuple3) ...
在上面的第一个语句中,即便是匹配成功也不会进行任何赋值操作:稳定标示符在模式匹配期间不会进行任何赋值。
小写的变量名同样可以使用重音符(`)包围的方式当做稳定标示符,同时它们必须是 val,因此把他们当做常量来处理:
final val theAnswer = 42
def checkGuess(guess: Int) = guess match {
case `theAnswer` => "Your guess is correct"
case _ => "Try again"
}
大写的变量名并声明为 var ,在 Scala 中是不推荐的做法,而且要完全避免。使用大写变量名来声明常量,同时,常量声明为 final。这样避免被子类覆写,同时编译器将他们内联(inline)以提升性能。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.