谈谈Scala中的枚举
先谈Java中的枚举
将Scala的枚举之前,我们先来讲讲关于Java里面的枚举(相信对于广大程序猿来说都是很熟悉):
使用
enum关键词定义1
public enum WeekDay{...}
无法再继承其他类或者枚举(但是可以实现接口),因为它默认继承了
java.lang.Enum- 无法在外部调用枚举的构造函数(因为枚举的构造函数都是私有的,只有内部才能调用)
- 枚举其实是一组
int常量(当初它就是因为使用int常量的需求很大才又了枚举),它还可以在swtich中很方便的使用 每个枚举变量还可以重写枚举类或者实现接口中的方法(这个蛮好用)
1
2
3
4
5
6
7
8
9
10
11
12public enum WeekDay{
Mon{
@Override
public String say(){return "monday";}
},
Tue{
@Override
public String say(){return "tuesday";}
};
public String say(){return "";}
}…(我也不知道了-_-)
再看Scala中的枚举
你会发现,上面说的一切在
Scala中其实并没有甚么卵用-_-,因为在Scala中压根就么有enum这个关键词,但是当初发明Scala大神兼Java的创始人并没有落下枚举。
Scala不用关注枚举的特别语法,取而代之的是标准库中的类:scala.Enumeration1
2
3
4
5
6
7
8
9
10
11
12object Main extends App {
object WeekDay extends Enumeration {
type WeekDay = Value//这里仅仅是为了将Enumration.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//使用语法糖进行输出
}
上述是源码中给的一个枚举Example,可以发现:
- 它是一个伴随对象
- 需要显式得继承
Enumeration - 具体的枚举实例都是需要赋值成
Value这个对象(它是在超类中定义)
Enumeration源码分析
构造函数以有变量
1 | /** Defines a finite set of values specific to the enumeration. Typically |
上面是洋洋洒洒贴了Enumeration类在Scala中的部分源码,从中大致可以看到这么几个关键点:
- 它提供了一个轻量级的枚举类
initial初始化变量为整个枚举实例的容量,但是它在运行时可以变化vmap:非常重要的一个变量,它是存储了枚举id和枚举值之间的映射容器。nmap:也是蛮重要的一个变量,存储了枚举id和枚举名称的容器**Id:所有带Id后缀的变量都是为了维护整个枚举的序号- 其他就是提供了各种迭代器,用于取值的东西
Value类的相关定义
1 | /** The type of the enumerated values. */ |
在源码的Example中可以看到所有的枚举都是被赋值为Value类型,从上面的源码中可以看到Value类是一个抽象类,看它的内容只是提供了枚举值比较以及id的获取,在Enumeration源码中提供了一个叫Val的类对Value实现,重要是重写了整数命名和id的识别。1
2
3
4
5
6
7
8
9
10
11/** A class implementing the [[scala.Enumeration.Value]] type. This class
* can be overridden to change the enumeration's naming and integer
* identification behaviour.
*/
@SerialVersionUID(0 - 3501153230598116017L)
protected class Val(i: Int, name: String) extends Value with Serializable {
def this(i: Int) = this(i, nextNameOrNull)
def this(name: String) = this(nextId, name)
def this() = this(nextId)
//to do many things.
}
Value方法的定义
请注意,请注意,Example中的第4行、第5行的
Value,前者是类,后者是方法(括号省略了而已)
1 | /** Creates a fresh value, part of this enumeration. */ |
上面提供了各种Value的重载方法均是返回了Val类,所以说嘛,你有需要完全可以自己再实现一个Value类。
Scala中枚举的简单使用
1 | println(WeekDay.Wed)//直接取枚举值 |
获取枚举的具体信息还是非常方便的
Wed
2
7
Wed
获取全部的枚举值进行输出1
WeekDay.values.foreach(println(_))
Mon
Tue
Wed
Thu
Fri
Sat
Sun
枚举也可以用在匹配
1 | matchTest(WeekDay.Wed) |
可以看到输出
sorry,please working
go shopping
这里的枚举值的比较其实就是对比他们的Id是否相等。
总结
Java中的那套枚举并不能直接使用到Scala中Scala中的枚举使用轻量级Enumeration进行实现Scala中的枚举其实是一个伴随对象Scala中的枚举没有方法重写功能Scala中的枚举其实都是Enumeration.Value这个对象
参考
- http://www.cnblogs.com/gnivor/p/4191017.html
Enumeration.scala
本作品采用[知识共享署名-非商业性使用-相同方式共享 2.5]中国大陆许可协议进行许可,我的博客欢迎复制共享,但在同时,希望保留我的署名权kubiCode,并且,不得用于商业用途。如您有任何疑问或者授权方面的协商,请给我留言。

