如何在Scala中定义的对象中迭代内部对象 [英] How to iterate inner objects in a defined object in Scala

查看:48
本文介绍了如何在Scala中定义的对象中迭代内部对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是如何使用 Scala reflection package 迭代 Scala 中定义的对象中的内部对象?

My question is how to iterate inner objects in a defined object in Scala using Scala reflection package?

object Units {

    val values = CITIZEN :: WORKER :: Nil // I need something reflectional to list all of the case objects

    case object CITIZEN extends Population
    case object WORKER extends Population
}

推荐答案

有很多方法可以做到这一点,但我建议使用宏(编译时反射)而不是运行时反射,为了性能和(更重要的是)类型安全.

There are lots of ways to do this, but I'd suggest using macros (compile-time reflection) over runtime reflection, for the sake of both performance and (more importantly) type safety.

这是一个使用宏的快速实现:

Here's a quick implementation with macros:

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)

请注意,编译器知道案例对象列表可以静态类型化为人口列表.

Note that the compiler knows that the list of case objects can be statically typed as a list of populations.

这篇关于如何在Scala中定义的对象中迭代内部对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆