【发布时间】:2012-08-26 09:54:48
【问题描述】:
有以下枚举
object ResponseType extends Enumeration {
val Listing, Album = Value
}
如何获得其 val 的列表?
【问题讨论】:
标签: scala reflection enumeration scala-2.10
有以下枚举
object ResponseType extends Enumeration {
val Listing, Album = Value
}
如何获得其 val 的列表?
【问题讨论】:
标签: scala reflection enumeration scala-2.10
如果您想彻底了解这一点,您需要检查您的符号是否具有 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。
【讨论】:
Enumeration#Value 的类型别名与上述过滤谓词匹配。要解决此问题,请查看! sym.isType。
以下代码获取代表“vals”的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 测试特定类型来实现,而不是过滤 is 子句,如下所示:
.collect{ case symbol : MethodSymbol => symbol }
反射 api 中的其他任务可能需要这种方法。
还应该注意,使用.view 根本不是强制性的,它只是使用一系列filter 应用程序(与map、flatMap 等许多其他功能一样多) .) 更有效,通过只遍历输入集合一次并且在它实际上被强制进入某个具体集合的点(在我们的例子中为.toList)。
正如 Travis Brown 所建议的,也可以直接引用 ResponseType 对象。所以typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre部分可以换成typeOf[ResponseType.type]
【讨论】:
typeOf[ResponseType.type].members...?如果不讨论动机,你的约束就会显得有些武断。
typeOf[ResponseType.Value] 的成员,这就是重点
ResponseType 的成员。
您可以通过返回的集合迭代枚举的值 枚举值方法:
scala> for (e <- ResponseType.values) println(e)
Listing
Album
【讨论】: