Scala / Java Enums

I 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 } } 
+4
source share
3 answers

In Scala, you can create an enumeration structure that is close to the "enum" from Java. Basically, you just need to extend the scala.Enumeration class and extend the Val class if you need a more complex class as an enumeration. Otherwise, you can use the default Val class, which accepts Int or String or Both. Below is the 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)) } 
+10
source

There is no direct comparison between the case class and enumerations, or something really close to enums. But you can implement similar logic as follows:

 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 put it in some list with values:

 import Status._ val values = List(OK, NOT_OK, BAD) 

and then follow these steps:

 values.foreach(doStuff) 

The result will be the same as in the Java version.

If you need to perform different actions depending on the type of status, you can go with the template:

 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 function of using the doStuff template use, for example:

 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) 
+4
source

You can use sealed class + case object . The only part you cannot deal with this approach is the values method, but you can use this answer to implement the values method as follows:

 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 
0
source

Source: https://habr.com/ru/post/1201426/


All Articles