Scala / Java枚举

时间:2014-02-03 20:33:04

标签: java scala enums idiomatic

我已阅读thisthis,但我仍然不理解在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
    }
}

3 个答案:

答案 0 :(得分:10)

在Scala中,您可以创建一个与Java“enum”接近的Enumeration结构。基本上,你需要做的只是扩展一个scala.Enumeration class并扩展一个Val类,如果你需要一个更复杂的类作为枚举。否则,您可以使用默认的Val类,它接受Int或String或Both。下面是Java代码的Scala版本。

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

答案 1 :(得分:4)

案例类和枚举之间没有直接映射,也没有真正接近枚举的东西。但是你可以用这种方式实现类似的逻辑:

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

然后,如果您愿意,可以将其放在一些名为值的列表中:

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

然后做你的东西:

values.foreach(doStuff)

结果与Java版本

相同

如果您需要执行取决于Status类型的不同操作,那么您可以使用模式匹配:

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

然后在你的doStuff函数中使用模式匹配,例如:

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)

答案 2 :(得分:0)

您可以使用sealed class + case object。使用此方法无法获得的唯一部分是方法values,但您可以使用this answer来实现方法values,如下所示:

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