2015-09-21 110 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,我不鼓勵這樣做。