Scala Enumerate (枚举)

来源:互联网 发布:延边电视台网络 编辑:程序博客网 时间:2024/05/16 04:51

Enumerate (枚举)

Scala中,没有语言级别的枚举类型,枚举的功能可以通过继承枚举类Enumeration实现。

继承枚举类

继承枚举类Enumeration可以在成员中使用无参方法Value给每个枚举成员赋值。
默认的Value方法会按变量名生成枚举名和并自动从0开始生成枚举ID,若需要手动设定枚举名称和枚举ID则可以使用Value方法的重载Value(id: Int, name: Strig)

如下所示:

object Color extends Enumeration {  // 自动赋值枚举成员  val Red, Green, Blue = Value  /*  * 相当于分别初始化:  * val Red = Value  * val Green = Value  * val Blue = Value  */  // 手动使用 Value(id: Int, name: String) 方法手动进行id和name的设置  // 使用重载有參版本的Value(id: Int, name: String)不能一次性给多个枚举成员赋值,会编译报错(id冲突)  val White = Value(100, "white")  val Black = Value(200, "black")}object TestEnumeration extends App {  Color.values foreach { color =>     println(s"ID: ${color.id}, Str: $color")  }}

输出结果:

ID: 0, Str: RedID: 1, Str: GreenID: 2, Str: BlueID: 100, Str: whiteID: 200, Str: black

Enumeration类的默认构造方法带有一个Int类型参数,用于指定枚举ID的起始大小,如下所示:

object Color extends Enumeration(100) {  val Red, Green, Blue, White, Black = Value //枚举Id将从100开始}object Main extends App {  Color.values foreach { color =>    println(s"ID: ${color.id}, Str: $color")  }}

输出结果:

ID: 100, Str: RedID: 101, Str: GreenID: 102, Str: BlueID: 103, Str: WhiteID: 104, Str: Black

访问枚举内容

枚举单例支持以多种形式访问:

  • 通过枚举成员访问,类似于其它常见编程语言(Enum.member)
  • 通过枚举ID进行访问,语法类似数组(Enum(id))
  • 通过枚举名称进行访问,使用withName成员方法(Enum withName "xxx")

枚举内部的成员全部保存在一个Set容器中,可使用values成员方法访问。

以前文中的Color单例对象为例,使用多种方式访问枚举内容,如下所示:

object Color extends Enumeration {  val Red, Green, Blue = Value  val White = Value(100, "white")  val Black = Value(200, "black")}object Main extends App {  def showEnum(color: Color.Value) = println(s"ID: ${color.id}, Str: $color")  // 通过枚举ID访问枚举  showEnum(Color(0))  showEnum(Color(100))  println()  // 通过枚举名称访问枚举  showEnum(Color withName "Green")  showEnum(Color withName "black")  println()  // 遍历枚举内容  Color.values foreach showEnum}

输出结果:

ID: 0, Str: RedID: 100, Str: whiteID: 1, Str: GreenID: 200, Str: blackID: 0, Str: RedID: 1, Str: GreenID: 2, Str: BlueID: 100, Str: whiteID: 200, Str: black

调用枚举类型

继承了枚举类的单例对象名并不能直接用于表示枚举类型。
对应的枚举类型应使用对象内部定义的抽象类型Value来表示,即单例对象名称.Value

以前文中的Color单例对象为例,对应的枚举类型应使用Color.Value表示。
将枚举做为参数传递,如下所示:

object Color extends Enumeration {  val Red, Green, Blue = Value  val White = Value(100, "white")  val Black = Value(200, "black")}object Main extends App {  // Xxx.Value才是真正的枚举类型  def showEnum(color: Color.Value) = println(s"ID: ${color.id}, Str: $color")  showEnum(Color.blue)  showEnum(Color.white)}

输出结果:

ID: 2, Str: BlueID: 100, Str: white

限定枚举类型

Scala通过使用单例继承Enumeration类来提供枚举功能,枚举值的类型实际为单例.Value
由于Scala中每个实例的内部类的类型均不相同,需要使用类型投影来表示通用的枚举类型。
枚举值的类型投影为Enumeration#Value
在泛型方法中,可以使用泛型约束T <: Enumeration#Value来限定泛型参数为枚举类型。
如下所示:

scala> def testEnum[T <: Enumeration#Value](enum: T) = println(enum) //打印枚举参数名称testEnum: [T <: Enumeration#Value](enum: T)Unitscala> object Enum extends Enumeration { val enum0, enum1  = Value }defined object Enumscala> testEnum(Enum.enum0) //传入枚举类型参数enum0scala> testEnum(Enum.enum1)enum1scala> testEnum(123) //使用其它类型不满足泛型约束,报错<console>:13: error: inferred type arguments [Int] do not conform to method testEnum's type parameter bounds [T <: Enumeration#Value]       testEnum(123)       ^<console>:13: error: type mismatch; found   : Int(123) required: T       testEnum(123)                ^

通过构建特定的枚举基类,可以实现限定指定类别的枚举。
如下所示:

scala> class MyEnumeration extends Enumeration //自定义枚举基类defined class MyEnumerationscala> def testMyEnum[T <: MyEnumeration#Value](enum: T) = println(enum) //限定枚举从自定义基类MyEnumeration中继承testMyEnum: [T <: MyEnumeration#Value](enum: T)Unitscala> object Enum extends Enumeration { val enum0, enum1  = Value } //普通枚举defined object Enumscala> object MyEnum extends MyEnumeration { val enum0, enum1  = Value } //从自定义基类MyEnumeration继承的枚举defined object MyEnumscala> testMyEnum(MyEnum.enum0) //参数为从自定义枚举基类MyEnumeration继承的枚举单例的枚举值,正常enum0scala> testMyEnum(MyEnum.enum1)enum1scala> testMyEnum(Enum.enum1) //参数为普通枚举单例的枚举值,错误<console>:14: error: inferred type arguments [Enum.Value] do not conform to method testMyEnum's type parameter bounds [T <: MyEnumeration#Value]       testMyEnum(Enum.enum1)       ^<console>:14: error: type mismatch; found   : Enum.Value required: T       testMyEnum(Enum.enum1)                       ^
原创粉丝点击