如何将宏用于简洁、类型安全、未装箱的枚举?

How to use macros for concise, type-safe, unboxed enum?

我正在学习 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 上出错。

已经尝试过(Alois Cochard 和 Simon Ochsenreither)以与 Java 枚举兼容的方式,但是 IIRC Scala 编译器不会将一些必需的标志发送到字节码中,并且项目卡着了。我知道的最新版本是 here.

不知道对你的想法是否有用。你需要研究语法,因为我不确定它是否会解析,你可能需要一些高级的宏(例如 scala meta)来实现它。

因此来自 Rex Kerr's , I figured out I needed to look at StaticAnnotation, then made a simplistic implementation here。对于我个人的使用,我认为没有必要与 Java 保持良好的互操作性,但我走了。

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