如何将宏用于简洁、类型安全、未装箱的枚举?
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 个备选方案的枚举表示为位,并对其集合进行有效的拆箱实现(如 Int
或 Long
)。
另一个令人信服的原因是我们还可以为 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 保持良好的互操作性,但我走了。
(允许我不要脸,接受我自己的回答^^)
我正在学习 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 个备选方案的枚举表示为位,并对其集合进行有效的拆箱实现(如 Int
或 Long
)。
另一个令人信服的原因是我们还可以为 enum
的稍微不同的风格定制不同的方面,例如,在上面,我们可以为 enum
提供一些参数,以便next
循环而不是在 Sunday
上出错。
已经尝试过(Alois Cochard 和 Simon Ochsenreither)以与 Java 枚举兼容的方式,但是 IIRC Scala 编译器不会将一些必需的标志发送到字节码中,并且项目卡着了。我知道的最新版本是 here.
不知道对你的想法是否有用。你需要研究语法,因为我不确定它是否会解析,你可能需要一些高级的宏(例如 scala meta)来实现它。
因此来自 Rex Kerr's StaticAnnotation
, then made a simplistic implementation here。对于我个人的使用,我认为没有必要与 Java 保持良好的互操作性,但我走了。
(允许我不要脸,接受我自己的回答^^)