简体   繁体   中英

Generic sealed trait fromString() method

Considering the following code :

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

Can I refactor the fromString() method to avoid having a case per case object instance ? Some more generic code able to enumerate through all Foo instances ?

In my real version, I start to have a lot of case object, and the wall of case bla.name => bla is boring me ^^

Thanks :)

How about something like this?

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

You can then use the withName(String) method to get the corresponding concrete object of type Foo as an 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!

Beachape provide an enum library which can do this for you out of the box:

include this in your build.sbt

"com.beachape" %% "enumeratum" % "1.5.15"

The Enum class provided just needs to be extended like so:

import enumeratum._

sealed trait Foo

object Foo extends Enum[Foo] {
  case object FooA extends Foo 
  case object FooB extends Foo 
}

There is a function called withName that will allow you to get the right sealed trait via its string name:

Foo.withName("FooA")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM