scala - 如何将共享的 Scala 枚举逻辑提取到特征或超类中?
问题描述
我需要定义一堆类似的枚举:
object Color extends MyEnum[Color.Color] {
type Color = Value
val Red, Green, Periwinkle = Value
}
object Shape extends MyEnum[Shape.Shape] {
type Shape = Value
val Square, Circle, Balbis = Value
}
我想将共享功能提取到抽象类或特征中,以支持 1)apply
和unapply
方法,以及 2)从枚举到其字符串表示的隐式转换:
abstract class MyEnum[T] extends Enumeration {
implicit def valueToString(value: T): String = value.toString
implicit def stringToValue(string: String): T = apply(string)
def unapply(arg: String): Option[T] =
values.find(_.toString == arg).map(_.asInstanceOf[T])
def apply(arg: String): T =
values.find(_.toString == arg)
.getOrElse(sys.error(s"Invalid value '$arg'"))
.asInstanceOf[T]
}
这不编译;当我在中添加类型参数时,由于某种原因MyEnum[Color.Color]
它会破坏类型。Value
有什么方法可以通过这种枚举语法获得我想要的东西,还是我需要切换到案例对象解决方案(或更复杂的东西)?
解决方案
本博客讨论 Scala 中的枚举地狱:scala-enumerations-hell
解决方案不是使用 Scala 的 Enumeration 类型,而是创建自己的 Enumeration 类。这是该博客的抽象类:
abstract class Enum[Enum : ClassTag] { self =>
val values = {
import runtime.universe._
val mirror = runtimeMirror(self.getClass.getClassLoader)
val classSymbol = mirror.classSymbol(self.getClass)
classSymbol.toType.members
.filter(_.isModule)
.map(symbol => mirror.reflectModule(symbol.asModule).instance)
.collect { case v: Enum => v }
}
def forName(name: String): Option[Enum] = values.find(_.name == name)
implicit class RichardEnum(enum: Enum) {
def name: String = enum.toString
}
}
还有一个框架可以为您提供:lloydmeta/enumeratum
推荐阅读
- solr - Solr geodist() 函数返回什么测量单位?
- javascript - 如何根据在基于类的组件中填充 n 毫秒值的数组制作 n 个 react.js 倒数计时器?
- docker - 访问正在运行的 docker 容器时重置连接
- php - 当我按下发布按钮时,WordPress 将我重定向到管理员中的所有帖子页面,而不是我的自定义帖子类型页面
- excel - Excel中可见单元格的条件最小值
- javascript - 点击单词后如何弹出图片和文字?html、css和js
- scala - 在scala Spark中连接UDF
- javascript - 使用 automator 将 javascript 应用于计算机上的本地文本文件
- javascript - TypeScript 说一个字符串是无效的,即使它在联合中?
- javascript - 如何访问在另一个 .js 文件中的一个 .js 文件中存在的异步函数中修改的变量?