【问题标题】:Built in parsing of a string to a Scala case object?内置将字符串解析为 Scala 案例对象?
【发布时间】:2011-11-23 17:00:07
【问题描述】:

在 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
  }
}

背景:我正在将我的案例对象转换为我在 html 表单中用作单选按钮值的字符串。当我处理提交的表单时,我将选定的值转换回案例对象。

相关信息:这实际上可以通过 Java 枚举实现,参见例如这个 StackOverflow 问题:Lookup enum by string value

((我不认为我在寻找 Scala 的解析器组合器。我想如果我使用它们我仍然需要自己定义解析规则,而不是内置“自动”字符串来区分大小写对象转换))

【问题讨论】:

  • 请注意,您的链接显示 C# 枚举。顺便说一句,你能提供一个场景,你真正需要这样的功能吗?
  • @agilesteel:我已经修复了链接,谢谢。我还添加了一些关于我为什么要进行这种转换的信息。

标签: parsing scala


【解决方案1】:

不,不会自动生成这样的方法。您必须编写自己的 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>" 获取特定的枚举值,或者使用Try(FlagReason withName "<name>").toOption 安全地作为Option

【讨论】:

  • 谢谢,extends Enumeration 之类的东西正是我所希望的 :-)
【解决方案2】:

正如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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多