use*_*503 4 scala compiler-errors match
我必须对Scala'匹配'语义或编译器逻辑有一些基本的误解.这段代码:
val stageStart:Int = 0
val stageShutDown:Int = Int.MaxValue
val stageErrorReport:Int = Int.MinValue
def stageString(stage:Int):String = stage match {
case stageStart => "Start"
case stageShutDown => "End"
case stageErrorReport => "Error"
case _ => "Step " + String.valueOf(stage)
}
Run Code Online (Sandbox Code Playgroud)
导致最后3'案例'陈述中出现"无法访问的代码"错误?如果你用实际值(0,Int.MaxValue,Int.MinValue)代替名称而不是它编译 - 但现在我已经硬编码了应该由它们的名称引用的值(出于所有通常的原因).既然'val'永远不会改变,那么第一个版本也不应该有效吗?
有一个微妙而重要的特性:如果case规则中的标识符以小写字母开头,则它们始终被视为变量.所以第一个case匹配总是(存储stage到变量stageStart),其余3个是不可达的.您需要使用大写字母定义常量
val StageStart:Int = 0
val StageShutDown:Int = Int.MaxValue
val StageErrorReport:Int = Int.MinValue
def stageString(stage:Int):String = stage match {
case StageStart => "Start"
case StageShutDown => "End"
case StageErrorReport => "Error"
case _ => "Step " + String.valueOf(stage)
}
Run Code Online (Sandbox Code Playgroud)
然后它们不会被视为变量,而是作为模式匹配的常量.
另请参阅此答案以了解Scala常量的命名约定?
问题是当您使用以小写字符开头的变量时,模式匹配器会认为您正在尝试分配给该变量.所以你得到这种行为:
val stageStart = 0
val stage = 5
def stageString(stage: Int) = stage match {
case stageStart => println(startStage) // prints "5"
}
Run Code Online (Sandbox Code Playgroud)
当然,只是一个可分配变量的模式将匹配任何东西,因此任何后续case都将无法访问.
要解决此问题,您需要使用"稳定标识符".这可以通过将小写变量放在反引号中来完成:
val stageStart = 0
def stageString(stage: Int) = stage match {
case `stageStart` => "Start"
}
Run Code Online (Sandbox Code Playgroud)
或重命名变量,使其以大写字符开头:
val StageStart = 0
def stageString(stage: Int) = stage match {
case StageStart => "Start"
}
Run Code Online (Sandbox Code Playgroud)
另外:String.valueOf(stage)应该改写为stage.toString.
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |