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

时间:2015-05-06 18:53:08

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

我正在学习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提供一些参数,以便{{} 1}}循环而不是next上的错误。

2 个答案:

答案 0 :(得分:3)

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

我不确定它是否适用于您的想法。你需要处理语法,因为我不确定它甚至会解析,你可能需要一些高级的宏(例如scala meta)才能将它拉下来。 / p>

答案 1 :(得分:1)

所以从Rex Kerranswer开始,我发现我需要查看StaticAnnotation,然后制作simplistic implementation here。对于我个人的用法,我认为没有必要保持与Java的良好互操作性,但我去了。

(请允许我无耻并接受我自己的回答^^)