我有一个相同类型的案例对象列表,例如
object Countries {
sealed abstract class Country (val name: String)
case object SE extends Country("Sweden")
case object AE extends Country("United Arab Emirates")
case object GB extends Country("United Kingdom")
case object US extends Country("United States of America")
}
现在我想创建一个这样的映射。
val map = Map[String, Country](
CH.name -> CH,
AE.name -> AE,
GB.name -> GB,
US.name -> US
)
所以我可以做到这一点,即。通过传递它的String键来获取对相应case对象的引用。
val us = Countries.map.get("United Kingdom")
有没有办法自动生成map
?
答案 0 :(得分:2)
object ReflectUtils {
import scala.reflect.runtime.universe.{TypeTag, typeOf}
def knownDirectSubclassesAsMap[T: TypeTag](keyGenerator: T => String): Map[String, T] =
typeOf[T].typeSymbol.asClass.knownDirectSubclasses.map { c =>
reflect.runtime.currentMirror.reflectModule(c.owner.typeSignature.member(c.name.toTermName).asModule).instance
}.asInstanceOf[Set[T]].map(obj => keyGenerator(obj) -> obj).toMap
}
然后:
object Countries {
sealed abstract class Country(val name: String)
case object SE extends Country("Sweden")
case object AE extends Country("United Arab Emirates")
case object GB extends Country("United Kingdom")
case object US extends Country("United States of America")
lazy val countriesByName = ReflectUtils.knownDirectSubclassesAsMap[Country](_.name)
def forName = countriesByName.apply _
}
即G。 Countries.forName("United States of America")
会返回Countries.US
个对象。