2015-09-21 111 views
1

我认为应该可以编写一个适用于所有枚举值的泛型函数。我第一次尝试一个简单的解析器,但我失败了:Scala:枚举值的泛型解析器

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函数获取枚举类型作为参数,并返回一个类型的值?我在这里与对象和内部类型具有相同的名称有点困惑。

+0

有点相关:https://stackoverflow.com/questions/21511656/declare-generic-method-returning-enumeration&https://stackoverflow.com/questions/14451152/scala-class-that-handles-enumerations-一般 – dskrvk

回答

1

首先,您的隐式方法valueToWeekday没有做任何事情,因为Weekday仅仅是Value在此上下文中的别名。其次,你的隐式方法stringToWeekday是一个工作的,虽然非通用的从字符串到枚举值的转换。但是,stringToWeekday通用并不难。您只需将枚举传递给函数,就像在parseEnumeration中那样。由于您在parseEnumeration中提供了隐含的证据,因此您只需在上下文中放置适当的隐式值即可。或者,您可以明确地传递证据。

所以你可以删除这些隐式转换(和类型别名,因为名称冲突有点误导)。

object Weekday extends Enumeration { 
    val Monday = Value("MONDAY") 
    val Other = Value("OTHER") 
} 
  1. 的含蓄的方式:

    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 
    
  2. 的明确方式:

    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作为证据,这是由编译器通过基因放入上下文中ric参数。但是,这需要反思来实际调用方法withName,我不鼓励这样做。