使用Scala的2.10思考如何列出枚举值?(Using Scala 2.10 reflection

2019-06-27 09:15发布

具有下列枚举

object ResponseType extends Enumeration {
  val Listing, Album = Value
}

我如何获得它的丘壑的名单?

Answer 1:

如果你想彻底了解这一点,你需要检查你的符号Value作为超:

def valueSymbols[E <: Enumeration: TypeTag] = {
  val valueType = typeOf[E#Value]
  typeOf[E].members.filter(sym => !sym.isMethod &&
    sym.typeSignature.baseType(valueType.typeSymbol) =:= valueType
  )
}

现在,即使你有以下(这是完全合法的):

object ResponseType extends Enumeration {
  val Listing, Album = Value
  val someNonValueThing = "You don't want this in your list of value symbols!"
}

你仍然得到正确的答案:

scala> valueSymbols[ResponseType.type] foreach println
value Album
value Listing

您当前的办法将包括value someNonValueThing这里。



Answer 2:

下面的代码获取列表Symbol代表“丘壑”的对象:

import reflect.runtime.universe._ // Access the reflection api

typeOf[ResponseType.Value]  //  - A `Type`, the basic unit of reflection api
  .asInstanceOf[TypeRef]    //  - A specific kind of Type with knowledge of
                            //    the place it's being referred from
  .pre                      //  - AFAIK the referring Type
  .members                  //  - A list of `Symbol` objects representing
                            //    all members of this type, including 
                            //    private and inherited ones, classes and 
                            //    objects - everything.
                            //    `Symbol`s are the second basic unit of 
                            //    reflection api.
  .view                     //  - For lazy filtering
  .filter(_.isTerm)         //  - Leave only the symbols which extend the  
                            //    `TermSymbol` type. This is a very broad 
                            //    category of symbols, which besides values
                            //    includes methods, classes and even 
                            //    packages.
  .filterNot(_.isMethod)    //  - filter out the rest
  .filterNot(_.isModule)
  .filterNot(_.isClass)
  .toList                   //  - force the view into a final List

应当指出的是,而不是筛选上,条款可与实施.collect针对特定类型的测试,如下所示:

.collect{ case symbol : MethodSymbol => symbol }

这种方法可能需要在反射API的其他任务。

还应该注意的是,使用.view不是强制性的话,那只是让使用一系列的filter的应用程序(多达许多其他功能,如mapflatMap更有效等),通过遍历输入收集只有一次,在那里它实际上是被迫到一些具体的集合(点.toList在我们的例子)。

更新

正如特拉维斯布朗建议的,但是也可以以引用ResponseType直接对象。 所以typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre部分可以被替换为typeOf[ResponseType.type]



Answer 3:

可以遍历通过由枚举的数值方法返回集合枚举值:

scala> for (e <- ResponseType.values) println(e)
Listing
Album


文章来源: Using Scala 2.10 reflection how can I list the values of Enumeration?