Scala不像Java那样有类型安全的枚举。给定一组相关的常量,在Scala中如何最好地表示这些常量?
当前回答
http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
示例使用
object Main extends App {
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)
WeekDay.values filter isWorkingDay foreach println
}
其他回答
声明命名枚举的一种稍微不那么冗长的方式:
object WeekDay extends Enumeration("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") {
type WeekDay = Value
val Sun, Mon, Tue, Wed, Thu, Fri, Sat = Value
}
WeekDay.valueOf("Wed") // returns Some(Wed)
WeekDay.Fri.toString // returns Fri
当然,这里的问题是,您需要保持name和val的顺序同步,如果name和val声明在同一行上,这将更容易做到。
在Scala中,https://github.com/lloydmeta/enumeratum非常适合
项目是非常好的例子和文档
他们文档中的这个例子应该会让你感兴趣
import enumeratum._
sealed trait Greeting extends EnumEntry
object Greeting extends Enum[Greeting] {
/*
`findValues` is a protected method that invokes a macro to find all `Greeting` object declarations inside an `Enum`
You use it to implement the `val values` member
*/
val values = findValues
case object Hello extends Greeting
case object GoodBye extends Greeting
case object Hi extends Greeting
case object Bye extends Greeting
}
// Object Greeting has a `withName(name: String)` method
Greeting.withName("Hello")
// => res0: Greeting = Hello
Greeting.withName("Haro")
// => java.lang.IllegalArgumentException: Haro is not a member of Enum (Hello, GoodBye, Hi, Bye)
// A safer alternative would be to use `withNameOption(name: String)` method which returns an Option[Greeting]
Greeting.withNameOption("Hello")
// => res1: Option[Greeting] = Some(Hello)
Greeting.withNameOption("Haro")
// => res2: Option[Greeting] = None
// It is also possible to use strings case insensitively
Greeting.withNameInsensitive("HeLLo")
// => res3: Greeting = Hello
Greeting.withNameInsensitiveOption("HeLLo")
// => res4: Option[Greeting] = Some(Hello)
// Uppercase-only strings may also be used
Greeting.withNameUppercaseOnly("HELLO")
// => res5: Greeting = Hello
Greeting.withNameUppercaseOnlyOption("HeLLo")
// => res6: Option[Greeting] = None
// Similarly, lowercase-only strings may also be used
Greeting.withNameLowercaseOnly("hello")
// => res7: Greeting = Hello
Greeting.withNameLowercaseOnlyOption("hello")
// => res8: Option[Greeting] = Some(Hello)
从Scala 3开始,现在有一个enum关键字,它可以表示一组常量(和其他用例)
enum Color:
case Red, Green, Blue
scala> val red = Color.Red
val red: Color = Red
scala> red.ordinal
val res0: Int = 0
我必须说,上面skaffman从Scala文档中复制的示例在实践中用处有限(您还可以使用case对象)。
为了获得最接近Java Enum的东西(即使用合理的toString和valueOf方法——也许你要将枚举值持久化到数据库中),你需要稍微修改它。如果你使用skaffman的代码:
WeekDay.valueOf("Sun") //returns None
WeekDay.Tue.toString //returns Weekday(2)
鉴于使用以下声明:
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon = Value("Mon")
val Tue = Value("Tue")
... etc
}
你会得到更合理的结果:
WeekDay.valueOf("Sun") //returns Some(Sun)
WeekDay.Tue.toString //returns Tue
http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
示例使用
object Main extends App {
object WeekDay extends Enumeration {
type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._
def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)
WeekDay.values filter isWorkingDay foreach println
}
推荐文章
- 我可以在Java中设置enum起始值吗?
- c# vs Java Enum(适合c#新手)
- 将JAR文件添加到Spark作业- Spark -submit
- Scala中的JavaConverters和JavaConversions有什么区别?
- TypeScript枚举对象数组
- 在Scala 2.8中<:<、<%<和=:=是什么意思?它们被记录在哪里?
- 从枚举中选择一个随机值?
- Scala vs Python的Spark性能
- 如何从枚举中选择一个随机值?
- c#中枚举中的方法
- 为什么在c++中声明enum时使用typedef ?
- 我如何在MySQL中添加更多的成员到我的enum类型列?
- 枚举上最常见的c#位操作
- 什么时候我应该在Scala中选择向量?
- 在Scala中,foldLeft和reducleft的区别