如何在类中使用Scala枚举

3
我正在学习Scala,并尝试为项目设置一个简单的枚举。我查看了一些示例,但没有一个适合,Scala文档和StackOverflow上的所有示例都是针对对象内部的枚举,而不是类。我得到了一个IDE警告,我不理解。我从初学者Java背景转入Scala,这可能是我困惑的原因。
以下是代码:
class Car(maxSpeed: Integer) {

  // Enums
  object CarType extends Enumeration {
    type CarType = Value
    val PERIPHERAL, COMPUTER, EMPTY = Value
  }
  import CarType._

  // Fields
   val repeated: CarType
}

当我将鼠标悬停在类名上时,我可以看到Intellij的警告:

类“Car”必须声明为抽象或实现抽象成员“typed:Car.this.CarType.CarType”中的“Car”

我不确定为什么它要求我实现我的变量,而且这个类并不打算是抽象的。我想以类似于Java中使用枚举的方式来使用它们。

2个回答

7
将枚举移到类外面:
// Enums
object CarType extends Enumeration {
  type CarType = Value
  val PERIPHERAL, COMPUTER, EMPTY = Value
}
class Car(maxSpeed: Integer) {
  import CarType._

  // Fields
   val repeated: CarType
}

或将其移至伴生对象

class Car(maxSpeed: Integer) {
  import Car.CarType._

  // Fields
   val repeated: CarType
}

object Car {
  object CarType extends Enumeration {
    type CarType = Value
    val PERIPHERAL, COMPUTER, EMPTY = Value
  }
}

问题在于类内定义的内容只能在该类的实例中使用(与其他一些语言不同)。

话虽如此,我建议使用代数数据类型而不是枚举:

sealed trait CarType
object CarType {
  case object Peripheral extends CarType // strange choice of names
  case object Computer extends CarType
  case object Empty extends CarType
}

case class Car(maxSpeed: Int, carType: CarType)

关于密封特质的更多信息,请参见SO问答。


你应该链接到伴生对象的文档:新的Scala用户可能不会非常容易地将静态方法/单例概念映射到伴生对象。 - Nathaniel Ford
谢谢。你的回答帮助我最好地解决了我的问题。我对stackoverflow的响应速度印象深刻,这是我第一次使用它,并且我在不到30分钟内得到了详细的回复。 - sudom82
将伴生对象移动到另一个文件并不适用于我。首先,scalastyle检查器抱怨相对引用import Car.CarType._。其次,我无法在Car类文件之外使用枚举。出现了一些关于期望类型为CarType.CarType但实际类型为CarType.Value的错误。可行的方法是老式的方式,即将枚举定义移到它自己的文件中。 - ruhong

0
你需要的是一个Scala Case Class
class Car(maxSpeed: Integer)
case class Minivan(maxSpeed: Integer) extends Car(maxSpeed: Integer)
case class Hodrod(maxSpeed: Integer) extends Car(maxSpeed: Integer)
case class Coupe(maxSpeed: Integer) extends Car(maxSpeed: Integer)

Java中存在的枚举在Scala中并不常用。通过像上面那样构建,您可以利用Scala强大的模式匹配来执行以下操作:

val unknownCar = getCar() // Some function that gets a car
unknownCar match {
  case Minivan => println("Driving the kids")
  case Hodrod => println("Tearing up the drag")
  case Coupe => println("Riding low")
}

...同时仍然允许您将其视为Car

由于它们是案例类,Scala有很多东西可以帮助您。

请注意枚举的文档

通常,这些值枚举某物可能采取的所有可能形式,并提供轻量级替代方案以替代案例类。

只有在您不打算将这些值用于其他任何事情时才应该使用它 - 但即使在那里,案例类通常也会更好地为您服务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接