内置将字符串解析为 Scala case 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7530039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:29:13  来源:igfitidea点击:

Built in parsing of a string to a Scala case object?

parsingscala

提问by KajMagnus

Is there any way to automatically parse a case object from a string, in Scala? Using some built in / automatically generated Scala function?

有没有办法在 Scala 中从字符串中自动解析 case 对象?使用一些内置/自动生成的 Scala 函数?

For example, I have these case objects: (please notethat there's a sealed parent class)

例如,我有这些 case 对象:(请注意有一个密封的父类)

abstract sealed class FlagReason

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

and I'm wondering if there's some automatically generated function that works like:

我想知道是否有一些自动生成的函数可以这样工作:

FlagReason.fromString(value: String): FlagReason

FlagReason.fromString(value: String): FlagReason

where FlagReason("Spam")would return the Spamcase object.

哪里FlagReason("Spam")会返回Spam案例对象。

If there were, then I need not write my own -- which I've done:

如果有,那么我不需要自己写——我已经完成了:

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

Background: I'm converting my case objects to strings that I use as radio button values in a html form. I'm converting the selected value back to a case object, when I handle the submitted form.

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

Related info: This is actually possible with Java enums, see e.g. this StackOverflow question: Lookup enum by string value

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

((I don't think I'm looking for Scala's Parser Combinators. I suppose that were I to use them I'd still need to define the parsing rules myself, rather than having built in "automatic" string to case object conversion))

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

回答by missingfaktor

No, no such method is automatically generated. You will have to write your own fromStringmethod. Note that you can write it more compactly as follows:

不,不会自动生成这样的方法。您将不得不编写自己的fromString方法。请注意,您可以更紧凑地编写如下:

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

Alternatively you may consider using scala.Enumerationwhich does provide this facility.

或者,您可以考虑使用scala.Enumerationwhich 提供此功能。

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

Then you can obtain the particular enum value with FlagReason withName "<name>", or safely as an Optionwith Try(FlagReason withName "<name>").toOption.

然后,您可以使用FlagReason withName "<name>"或安全地作为Optionwith获取特定的枚举值Try(FlagReason withName "<name>").toOption

回答by Otavio Macedo

As missingfaktorpoints out, FlagReason withName "<name>"should do what you need. But if <name>is not a valid name, it will throw an exception. So, a slightly safer way to handle this when you are not sure if the name is valid is to use Option[FlagReason]:

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