首页 > 解决方案 > 使用冒号冒号语法区分大小写的 Scala List 解包

问题描述

我想知道使用::语法进行列表解包的编译结果的一个奇怪问题。根据我的测试,编译结果取决于第一个字母的大小写,我试图找出原因:(我添加了来自 scala REPL 的日志)

scala> val smallExample :: Nil = (0 until 1).toList // works
val smallExample: Int = 0

scala> val CapitalExample :: Nil = (0 until 1).toList // fails with compile error
           ^
       error: not found: value CapitalExample

我想使用这种语法来构建类似于 C 枚举的东西,而不必手动指定所有索引,但我需要 ALL_CAPS_UNDERSCORE 来遵守命名约定。

您是否在不必指定所有常量(至少 32 个)或忽略命名约定的情况下输入替代方案?

详细说明我的用法:我正在尝试在 Chisel 中构建一个小型 RISC-V CPU,并且我需要从 0 到 31: 的列表中的所有操作码 LOAD :: LOAD_FP :: CUSTOM_1 :: MISC_MEM :: ... :: RESERVED_80BIT :: Nil = (0 until 32).toList,显然我不想明确指定所有这些数字。

谢谢!

标签: listscalacase-sensitive

解决方案


在模式匹配中(解构赋值是模式匹配的一种特殊情况),变量匹配和常量匹配都是可能的:

match {
  case x => ???    // a variable match
  case Nil => ???  // a constant match (not actually reachable)
}

为了消除这些情况的歧义,语言规范规定了一个规则,即以小写字母开头的简单名称是一个变量,而任何其他简单名称都被解释为一个常量。

如果用反引号括起来,语言规范要求以小写字母开头的简单名称被视为常量:

val pi = 3.14
math.E match {
  case `pi` => "Strange math?"
  case _ => "Seems OK"
}

语言规范不包括强制以非小写字母开头的简单名称被解释为模式匹配中的变量的方法。


推荐阅读