【问题标题】:Can I use @switch and Enumerations?我可以使用@switch 和枚举吗?
【发布时间】:2015-03-02 13:43:41
【问题描述】:

我可以使用 switch-case 对枚举进行模式匹配吗?

我试过了

import scala.annotation.switch

object Foo extends Enumeration {
  val First = Value
  val Second = Value
  val Third = Value
}

object Main {
  def foo(x: Foo.Value) = (x: @switch) match {
    case Foo.First => 1
    case Foo.Second => 2
    case Foo.Third => 3
  }
}

但收到以下警告(Scala 2.11.4):

warning: could not emit switch for @switch annotated match
  def foo(x: Foo.Value) = (x: @switch) match {

然后我尝试在 Java 中定义枚举,因为 Java 的 enums 与 Scala 的 Enumeration 不同。还是没有运气。

@switch 模式匹配仅适用于原始类型?

【问题讨论】:

    标签: scala enums switch-statement pattern-matching scala-2.11


    【解决方案1】:

    为了完成 Regis 的回答,Joshua Suereth 在 Scala In Depth 中指出,Scala 应用 tableswitch 优化必须满足以下条件:

    1. 匹配的值必须是已知整数。
    2. 匹配的表达式必须是“简单的”。它不能包含任何类型检查、if 语句或提取器。
    3. 表达式的值还必须在编译时可用。
    4. 应该有两个以上的 case 语句。

    Foo 对象不符合上述任何条件,尽管它不是 tableswitch 优化的主题。

    【讨论】:

      【解决方案2】:

      switch 注释的重点是确保您的匹配被编译成tableswitchlookupswitch JVM 指令。这些指令仅适用于整数,这意味着switch 注释只会对可以安全地放入Int 的类型产生任何影响。含义 Int 本身以及 CharByteShortBoolean。此外,您匹配的值必须是文字值(与存储在val 中的值相反)。鉴于 Enumeration 是一个参考值,它们与 switch 注释不兼容。对文字值的限制实际上意味着可能无法对ShortByte 使用此注解,纯粹出于语法原因,因为scala 中不支持文字short 和bytes:你必须使用文字int以及123: Byte 中的类型归属,但这不被接受为模式。 这样就只剩下IntCharBoolean 作为有效类型(至少可以说,使用@switch 作为布尔值的有用性是值得怀疑的)

      【讨论】:

      • 尽管 Java 在枚举上的 switch-case 会导致 tableswitch / lookupswitch。但是,是的,看来我的选择是(1)编写 Java,或者(2)如你所说,使用原始类型。
      • 这里的重要区别是Java枚举具有内置的语言支持,而Scala枚举纯粹是在标准库中定义的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多