问题
I've read this and this, but I still don't understand the (idiomatic) equivalent way to do this in Scala
enum Status {
OK(1, "Ok", "Okay"),
NOT_OK(5, "Not Ok", "Not Okay")
BAD(10, "Bad", "Run for your life")
int code;
String name;
String description; // custom fields
Status(int code, String name, String description) {
this.code = code;
this.name = name;
this.description = description;
}
}
class Main {
public static void main(String[] args) {
for(Status status : Status.values) { // iterate through them
doStuff(status);
}
}
private doStuff(Status status) {
System.out.println(status.description);
// and more
}
}
回答1:
In Scala you can create a Enumeration structure which is close to "enum" from Java. Basically, what you need to do is just to extend a scala.Enumeration class and to extend a Val class if you need a more complicated class as a enum. Otherwise, you can use default Val class which takes Int or String or Both. Below, is a Scala version of your Java code.
object Status extends Enumeration {
case class StatusVal(code: Int, name: String, description: String) extends Val
val OK = StatusVal(1, "Ok", "Okay")
val NOT_OK = StatusVal(1, "Not Ok", "Not Okay")
val BAD = StatusVal(1, "Bad", "Run for your life")
}
object Application extends App {
Status.values foreach (s => println(s.asInstanceOf[StatusVal].description))
}
回答2:
There is no direct mapping between case class and enumerations or something really close to enumerations either. But you can implement similar logic this way:
case class Status(code: Int, name: String, descr: String)
object Status {
val OK = Status(1, "Ok", "Okay"),
val NOT_OK = Status(5, "Not Ok", "Not Okay")
val BAD = Status(10, "Bad", "Run for your life")
}
Then if you want you can place it in some list called values:
import Status._
val values = List(OK, NOT_OK, BAD)
and then do your stuff:
values.foreach(doStuff)
The result would be the same like in Java version
If you need to execute different actions which depends on type of Status, then you can go with pattern matching:
sealed trait Status
case class OK(code: Int, name: String, descr: String) extends Status
case class Not_Ok(code: Int, name: String, descr: String) extends Status
case class Bad(code: Int, name: String, descr: String) extends Status
then in your doStuff function use pattern matching, e.g:
def doStuff(status: Status) = status match {
case OK(c, n, d) => // some code..
// some code for other cases
}
val values = List(OK(1, "Ok", "Okay"), Not_Ok(5, "Not Ok", "Not Okay"), Bad(10, "Bad", "Run for your life"))
value.foreach(doStuff)
回答3:
You could use sealed class
+ case object
. The only part you can't get with this approach is method values
, but you could use this answer to implement method values
like this:
sealed class Status(val code: Int, val name: String, val description: String)
object Status {
def values: Set[Status] = macro SealedExample.values_impl[Status]
case object OK extends Status(1, "Ok", "Okay")
case object NOT_OK extends Status(5, "Not Ok", "Not Okay")
case object BAD extends Status(10, "Bad", "Run for your life")
}
def doStuff(status: Status) = println(status.description)
for {s <- Status.values}
doStuff(s)
// Okay
// Not Okay
// Run for your life
来源:https://stackoverflow.com/questions/21537148/scala-java-enumerations