考虑以下代码:
sealed trait Foo {
def name: String
}
case object FooA extends Foo {
override val name: String = "a"
}
case object FooB extends Foo {
override val name: String = "b"
}
object Foo {
def fromString(name: String): Foo = {
name match {
case FooA.name => FooA
case FooB.name => FooB
}
}
我可以重构fromString()方法以避免每个案例对象实例有一个案例吗?一些更通用的代码能够枚举所有Foo实例?
在我的真实版本中,我开始有很多案例对象,case bla.name => bla
的墙壁让我很无聊^^
谢谢:)
答案 0 :(得分:1)
这样的事情怎么样?
sealed trait Foo {
def name: String
}
object Foo {
case object FooA extends Foo {
override val name: String = "a"
}
case object FooB extends Foo {
override val name: String = "b"
}
val values = Seq(FooA, FooB)
def withName(name: String): Option[Foo] = {
values.find(value => value.name.equals(name))
}
}
然后,您可以使用withName(String)
方法将相应类型为Foo
的具体对象作为Option
:
val testFooAName = "a"
val testFooA = Foo.withName(testFooAName) // Will yield Some(FooA)
testFooA match {
case Some(Foo.FooA) => println("Matched Foo.FooA!")
case Some(Foo.FooB) => println("Matched Foo.FooB!")
}
val testFooNoneName = "none"
val testFooNone = Foo.withName(testFooNoneName) // Will yield None
Output:
Matched Foo.FooA!
答案 1 :(得分:1)
Beachape提供了一个枚举库,可以立即为您完成此操作:
将此包含在您的build.sbt
"com.beachape" %% "enumeratum" % "1.5.15"
提供的Enum
类只需要像这样扩展:
import enumeratum._
sealed trait Foo
object Foo extends Enum[Foo] {
case object FooA extends Foo
case object FooB extends Foo
}
有一个名为withName
的函数,通过它的字符串名称,您可以获取正确的密封特征:
Foo.withName("FooA")