我认为应该可以编写一个适用于所有Enumeration值的泛型函数。我先尝试了一个简单的解析器,但是我失败了:
object Weekday extends Enumeration {
type Weekday = Value
val MONDAY = Value("MONDAY")
val OTHER = Value("OTHER")
implicit def valueToWeekday(v: Value): Weekday = v.asInstanceOf[Weekday]
implicit def stringToWeekday(s: String): Weekday = Weekday.withName(s)
}
object Enumerations {
import Weekday._
println("Welcome to the Scala worksheet")
def parseEnumeration[T <: Enumeration](s: String)(implicit ev: T): T#Value = {
ev.withName(s)
}
val test = parseEnumeration[Weekday]("MONDAY")
}
那么如何编写一个generict函数,将枚举类型作为参数并返回该类型的值?我在这里与Object和同名的内部类型有点混淆。
答案 0 :(得分:1)
首先,您的隐式方法valueToWeekday
并没有真正做任何事情,因为Weekday
只是此上下文中Value
的别名。
其次,隐式方法stringToWeekday
是一个有效的,尽管是从字符串到其枚举值的非泛型转换。
但是,stringToWeekday
通用并不难。您只需将枚举传递给函数,就像在parseEnumeration
中一样。由于您在parseEnumeration
中隐含了证据,因此您需要做的就是在上下文中添加适当的隐式值。或者,您可以明确传递证据。
因此,您可以删除这些隐式转换(以及类型别名,因为名称冲突有点误导)。
object Weekday extends Enumeration {
val Monday = Value("MONDAY")
val Other = Value("OTHER")
}
隐含的方式:
def parseEnumeration[T <: Enumeration](s: String)(implicit ev: T): T#Value = ev.withName(s)
implicit val evidence = Weekday
val weekday = parseEnumeration("MONDAY") // results in the value Weekday.Monday
明确的方式:
def parseEnumeration[T <: Enumeration](s: String, enumeration: T): T#Value = enumeration.withName(s)
val weekday = stringToEnumerationValue("MONDAY", Weekday) // results in the value Weekday.Monday
第三种选择是使用ClassTag
作为证据,编译器通过通用参数将其置于上下文中。但是,这需要反射来实际调用方法withName
,我不鼓励这样做。