【问题标题】:Scala List unpacking with colon colon syntax case sensitivity使用冒号冒号语法区分大小写的 Scala List 解包
【发布时间】:2021-10-26 20:02:02
【问题描述】:

我想知道使用:: 语法对列表解包的编译结果有一个奇怪的问题。根据我的测试,编译结果取决于第一个字母的大小写,我试图找出原因: (我已经从 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,显然我不想明确指定所有这些数字。

谢谢!

【问题讨论】:

  • 我不明白为什么你需要使用这种语法。你能详细说明一下吗?
  • 我尝试在整个语句和名称本身周围加上括号,但无济于事。 RE用法,我已经编辑了问题
  • 无论如何,您都必须编写 32 个变量名称,我认为这样做没有太大价值,而不是 32 个不同的变量。您还可以使用带有序号值的常规 Java 枚举。
  • 在模式匹配大写字母时,大小写意味着您要匹配一个已经存在的常量。这就是允许您在末尾匹配 Nil 而不是创建新变量的原因。
  • 对于第一种情况,这意味着我必须重复所有违反 DRY 原则的数字,并且使用序数会使代码非常混乱,因为这些数字经常需要

标签: list scala case-sensitive


【解决方案1】:

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

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"
}

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

【讨论】:

    猜你喜欢
    • 2019-09-14
    • 2014-01-31
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2015-09-09
    相关资源
    最近更新 更多