dotty编译器语法特性之一枚举类型

一个枚举是用来定义一个类型,这个类型是命名值类型的集合。
翻译: http://dotty.epfl.ch/docs/reference/enums/enums.html#implementation

enum Color {
  case Red, Green, Blue
}

这里定义了一个新的sealedColor,带有三个值: Color.Red, Color.Green, Color.Blue.这些颜色值是Color伴随对象的成员,以上Color的定义和下面更明确的enum class和伴随对象的定义是等价的:

enum class Color
object Color {
  case Red
  case Green
  case Blue
}

参数化枚举

枚举类可以被参数化.

enum Color(val rgb: Int) {
  case Red   extends Color(0xFF0000)
  case Green extends Color(0x00FF00)
  case Blue  extends Color(0x0000FF)
}

由这个例子所示,你可以通过extends语句来参数化枚举.

枚举类型所定义的方法

一个枚举的值对应一个唯一的整数,这个整数可以通过enumTag方法返回.

scala> val red = Color.Red
val red: Color = Red
scala> red.enumTag
val res0: Int = 0

一个枚举类的伴随对象也定义三个方法。 这个enumValueenumValueNamed 方法通过他的标签和名称获取值. 这个enumValues 方法获得所有枚举的值,存储在Iterable集合中。

scala> Color.enumValue(1)
val res1: Color = Green
scala> Color.enumValueNamed("Blue")
val res2: Color = Blue
scala> Color.enumValues
val res3: collection.Iterable[Color] = MapLike(Red, Green, Blue)

枚举的自定义方法

你能在枚举类或伴随对象中添加自定义方法。你必须用更长的语法定义一个枚举类和他的伴随对象.下面的例子中,类Planet定义了成员参数和成员相关的方法,在他的伴随对象中定义了枚举的所有值和入口方法main

enum class Planet(mass: Double, radius: Double) {
  private final val G = 6.67300E-11
  def surfaceGravity = G * mass / (radius * radius)
  def surfaceWeight(otherMass: Double) =  otherMass * surfaceGravity
}

object Planet {
  case MERCURY extends Planet(3.303e+23, 2.4397e6)
  case VENUS   extends Planet(4.869e+24, 6.0518e6)
  case EARTH   extends Planet(5.976e+24, 6.37814e6)
  case MARS    extends Planet(6.421e+23, 3.3972e6)
  case JUPITER extends Planet(1.9e+27,   7.1492e7)
  case SATURN  extends Planet(5.688e+26, 6.0268e7)
  case URANUS  extends Planet(8.686e+25, 2.5559e7)
  case NEPTUNE extends Planet(1.024e+26, 2.4746e7)

  def main(args: Array[String]) = {
    val earthWeight = args(0).toDouble
    val mass = earthWeight/EARTH.surfaceGravity
    for (p <- enumValues)
      println(s"Your weight on $p is ${p.surfaceWeight(mass)}")
  }
}

枚举的具体实现

枚举类是个sealed类,继承自scala.Enum trait,这个trait定义了唯一个方法enumTag:

package scala

/** A base trait of all enum classes */
trait Enum {

  /** A number uniquely identifying a case of an enum */
  def enumTag: Int
}

使用extends语句枚举的值,同样可以展开为匿名类实例,比如:

val VENUS: Planet =
  new Planet(4.869E24, 6051800.0) {
    def enumTag: Int = 1
    override def toString: String = "VENUS"
    // internal code to register value
  }

而没有使用extends语句的所有枚举值共享单一实例,这个实例使用带有一个标签和名称的私有方法实例化,比如上面的Color.Red展开为:

val Red: Color = $new(0, "Red")

转载于:https://my.oschina.net/jackywyz/blog/1489157

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值