2011-09-23 74 views
16

有什麼方法可以在Scala中自動從一個字符串中分析一個case對象嗎?使用一些內置/自動生成的Scala函數?建立在一個字符串解析Scala案例對象?

例如,我有這些情況的對象:(請注意,有一個密封的父類)

abstract sealed class FlagReason 

case object Spam extends FlagReason 
case object Illegal extends FlagReason 
case object CopyrightViolation extends FlagReason 
case object Other extends FlagReason 

,我想知道,如果有一些自動生成功能的工作原理是:

FlagReason.fromString(value: String): FlagReason

其中FlagReason("Spam")將返回Spam個案對象。

如果有,那麼我不用寫我自己 - 我已經做了:

object FlagReason { 
    def fromString(value: String): FlagReason = value match { 
    case "Spam" => Spam 
    case "Illegal" => Illegal 
    case "CopyrightViolation" => CopyrightViolation 
    case "Other" => Other 
    } 
} 

背景:我將我的情況下反對我的單選按鈕值使用字符串以html的形式。當我處理提交的表單時,我將選定的值轉換回一個case對象。

相關信息:這對於Java枚舉實際上是可行的,參見例如這StackOverflow的問題:Lookup enum by string value

((我不認爲我正在尋找斯卡拉的解析器組合,我想我是用它們,我仍然需要自己定義解析規則,而不是內置「自動」字符串到個案對象轉換))

+0

注意,你的鏈接顯示C#枚舉。順便說一句,你能提供一個場景,你真的需要這樣一個功能嗎? – agilesteel

+0

@agilesteel:我已經修復了這個鏈接,謝謝。我還添加了一些信息,說明我爲什麼要進行這種轉換。 – KajMagnus

回答

25

不,不會自動生成此類方法。你將不得不編寫你自己的fromString方法。請注意,您可以按以下更緊湊寫:

object FlagReason { 
    def fromString(value: String): Option[FlagReason] = { 
    Vector(Spam, Illegal, CopyRightViolation, Other).find(_.toString == value) 
    } 
} 

另外,您可以考慮使用scala.Enumeration它確實提供了這一設施。

object FlagReason extends Enumeration { 
    val Spam, Illegal, CopyRightViolation, Other = Value 
} 

然後你就可以用FlagReason withName "<name>"獲得特定枚舉值,或安全爲OptionTry(FlagReason withName "<name>").toOption

+0

謝謝,像'extends Enumeration'這樣的東西是我所希望的:-) – KajMagnus

3

由於missingfaktor指出,FlagReason withName "<name>"應該做你需要的。但是,如果<name>不是有效的名稱,則會引發異常。所以,稍微更安全的方式來處理這個時候你是不知道,如果名稱是有效的方法是使用Option[FlagReason]

scala> def parse(name: String) = FlagReason.values.find(_.toString == name) 
parse: (name: String)Option[FlagReason.Value] 

scala> parse("Spam") 
res0: Option[FlagReason.Value] = Some(Spam) 

scala> parse("NonExisting") 
res1: Option[FlagReason.Value] = None