扩展Scala Enumeration.Val时如何获取正确的值类型

时间:2014-04-16 22:49:45

标签: scala enumeration

虽然关于Scala Enumeration的困难有很多关于S / O的问题,但我没有找到解决我的问题的问题。具体来说,我试图将Planet示例从Oracle Java enum docs转换为Scala Enumeration惯用法,以便更好地理解工作原理和专业人员。斯卡拉形式的概念。

到目前为止,我的移植代码如下所示,并且足以说明,它不会按照最小惊喜的原则进行编译。除了使用.asInstanceOf进行类型转换外,是否有更好的或可接受的解决方案?

谢谢,贾斯汀

    object Planet extends Enumeration {

  // universal gravitational constant (m3 kg-1 s-2)
  val G = 6.67300E-11

  val Mercury = Planet(3.303e+23, 2.4397e6)
  val Venus = Planet(4.869e+24, 6.0518e6)
  val Earth = Planet(5.976e+24, 6.37814e6)
  val Mars = Planet(6.421e+23, 3.3972e6)
  val Jupiter = Planet(1.9e+27, 7.1492e7)
  val Saturn = Planet(5.688e+26, 6.0268e7)
  val Uranus = Planet(8.686e+25, 2.5559e7)
  val Neptune = Planet(1.024e+26, 2.4746e7)

  case class Planet(mass: Double, radius: Double) extends Val {

    def surfaceGravity: Double = G * mass / (radius * radius)

    def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity

  }

}

object PlayEnumeration extends App {


  val earthWeight = 175
  val mass = earthWeight / Planet.Earth.surfaceGravity

  Planet.values.foreach {
    // Does not compile as might be expected.
    // value surfaceWeight is not a member of play.Planet.Value
    p => println(s"Your weight on $p is ${p.surfaceWeight(mass)}")
  }

  println

}

2 个答案:

答案 0 :(得分:0)

尝试使用asInstanceOf [Planet]

将枚举值强制转换为Planet
object PlanetEnum extends Enumeration {

  // universal gravitational constant (m3 kg-1 s-2)
  val G = 6.67300E-11

  val Mercury = Planet(3.303e+23, 2.4397e6)
  val Venus = Planet(4.869e+24, 6.0518e6)
  val Earth = Planet(5.976e+24, 6.37814e6)
  val Mars = Planet(6.421e+23, 3.3972e6)
  val Jupiter = Planet(1.9e+27, 7.1492e7)
  val Saturn = Planet(5.688e+26, 6.0268e7)
  val Uranus = Planet(8.686e+25, 2.5559e7)
  val Neptune = Planet(1.024e+26, 2.4746e7)

  case class Planet(mass: Double, radius: Double) extends Val {

    def surfaceGravity: Double = G * mass / (radius * radius)

    def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity

  }

}

object PlayEnumeration extends App {

  val earthWeight = 175
  val mass = earthWeight / PlanetEnum.Earth.surfaceGravity

  PlanetEnum.values.foreach {
    p => println(s"Your weight on $p is ${p.asInstanceOf[Planet].surfaceWeight(mass)}")

  }

  println

}

答案 1 :(得分:0)

将以下行添加到object Planet

implicit def convert(value: Value): Planet = value.asInstanceOf[Planet]

这充分利用了Scala中隐含的非凡力量。

如果您正在寻找可以提供更多灵活性的东西(特别是详尽的模式匹配),我只需要posted an answer showing my general solution进行Scala中的枚举。

在对选项进行广泛研究之后,该解决方案是对该领域的更全面的概述,包括解决“密封特征+案例对象”模式,其中我最终解决了JVM类/对象初始化排序问题。