【问题标题】:How to use macros for concise, type-safe, unboxed enum?如何使用宏进行简洁、类型安全、未装箱的枚举?
【发布时间】:2015-07-17 02:12:48
【问题描述】:

我正在学习 Scala 宏并将其视为一种练习。

是否可以使用 Scala 宏来写下这样的东西(可能不完全是这个具体的语法,而是没有样板的东西)

enum DayOfWeek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

并让它宏扩展成这样的东西?

class DayOfWeek private (val ord: Int) extends AnyVal {

  def next: DayOfWeek = ord match {
    case 0 => Tuesday
    case 1 => Wednesday
    case 2 => Thursday
    case 3 => Friday
    case 4 => Saturday
    case 5 => Sunday
    case _ => throw Error("Sunday does not have next")
  }

  override def toString: String = ord match {
    case 0 => "Monday"
    case 1 => "Tuesday"
    case 2 => "Wednesday"
    case 3 => "Thursday"
    case 4 => "Friday"
    case 5 => "Saturday"
    case _ => "Sunday"
  }
}

object DayOfWeek {
  def count = 7

  val Monday    = new DayOfWeek(0)
  val Tuesday   = new DayOfWeek(1)
  val Wednesday = new DayOfWeek(2)
  val Thursday  = new DayOfWeek(3)
  val Friday    = new DayOfWeek(4)
  val Saturday  = new DayOfWeek(5)
  val Sunday    = new DayOfWeek(6)
}

也许不一定使用连续的整数来表示枚举。例如,使用一些标志,我们可以将不超过 32 或 64 个替代项的枚举表示为位,并对其集合进行有效的未装箱实现(如 IntLong)。

另一个令人信服的理由是我们还可以为 enum 的稍微不同的风格定制不同的方面,例如,在上面,我们可以为 enum 提供一些参数,以便 next 循环Sunday 上的错误。

【问题讨论】:

标签: scala enums metaprogramming value-type scala-macros


【解决方案1】:

这已经尝试(由 Alois Cochard 和 Simon Ochsenreither)以与 Java 枚举兼容的方式进行,但是 IIRC Scala 编译器不会将一些必需的标志发送到字节码中,因此项目陷入困境。我知道的最新版本是here

我不确定它是否对您的想法有用。您需要处理语法,因为我不确定它是否会解析,并且您可能需要一些高级的宏(例如scala meta)来实现它。

【讨论】:

  • 这绝对是相关的。我会研究代码。非常感谢!
【解决方案2】:

所以从Rex Kerranswer,我发现我需要查看StaticAnnotation,然后创建了simplistic implementation here。就我个人的使用而言,我认为没有必要与 Java 保持良好的互操作性,但我去吧。

(请允许我不要脸,接受我自己的答案^^)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多