有很多方法可以做到这一点,但为了性能和(更重要的是)类型安全,我建议在运行时反射上使用宏(编译时反射)。
这是一个使用宏的快速实现:
import scala.language.experimental.macros
object MacroUtils {
import scala.reflect.macros.Context
def values = macro MacroUtils.values_impl
def values_impl(c: Context) = {
import c.universe._
val objs = c.enclosingClass.collect {
case ModuleDef(mods, name, _) if mods hasFlag Flag.CASE => Ident(name)
}
c.Expr[List[Any]](
Apply(Select(reify(List).tree, newTermName("apply")), objs.toList)
)
}
}
trait Population
object Units {
val values = MacroUtils.values
case object CITIZEN extends Population
case object WORKER extends Population
}
然后,例如:
scala> val populations: List[Population] = Units.values
populations: List[Population] = List(CITIZEN, WORKER)
请注意,编译器知道案例对象列表可以静态类型化为总体列表。