有没有办法在Scala中自动解析字符串中的case对象?使用一些内置/自动生成的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
}
}
背景:我正在将我的case对象转换为我用作html格式的单选按钮值的字符串。当我处理提交的表单时,我正在将选定的值转换回案例对象。
相关信息:这实际上可以使用Java枚举,例如,这个StackOverflow问题:Lookup enum by string value
((我不认为我在寻找Scala的Parser Combinators。我想我要使用它们我仍然需要自己定义解析规则,而不是内置“自动”字符串到案例对象转换))
答案 0 :(得分:28)
不,不会自动生成此类方法。您必须编写自己的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>"
获取特定的枚举值,或使用Option
安全地获取Try(FlagReason withName "<name>").toOption
。
答案 1 :(得分: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