我想使用Enumeration作为类型参数,编译器让我感到悲伤。
object VehicleClass extends Enumeration {
type VehicleClass = Value
val Land, Air, Sea = Value
}
import VehicleClass._
trait Vehicle[K <: VehicleClass] { val kind: K }
case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
编译抱怨:
[error] /Users/me/test/scala/co.blocke.scalajack/json/test.misc/Greg.scala:18: not found: type Land
[error] case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
[error] ^
[error] /Users/me/test/scala/co.blocke.scalajack/json/test.misc/Greg.scala:18: not found: type Land
[error] case class Car(passengers: Int) extends Vehicle[Land] { val kind: Land }
[error] ^
如何做到这一点?
答案 0 :(得分:2)
你可以写
case class Car(passengers: Int) extends Vehicle[Land.type] {
val kind: Land.type = Land
}
Land.type
是Land
的单例类型,即唯一值为Land
的类型(不包括null
)。
答案 1 :(得分:1)
Alexey为使用scala.Enumeration
我会使用ADT而不是我认为已弃用的枚举来解决此问题。 (见http://underscore.io/blog/posts/2014/09/03/enumerations.html)
以下是使用ADT的解决方案
// Using an abstract class makes accessing things in VehicleClass companion
// object nicer
sealed abstract class VehicleClass
case object Land extends VehicleClass
case object Air extends VehicleClass
case object Sea extends VehicleClass
trait Vehicle[K <: VehicleClass] { val kind: K }
case class Car(passengers: Int) extends Vehicle[Land.type] { val kind = Land }
我会稍微简化一下这段代码,因为通常看不到要求使trait Vehicle
通用。这增加了什么额外的安全性?我通常会将特性简化为
trait Vehicle { val kind: VehicleClass }
(我可以看到Vehicle
泛型的唯一原因是为Vehicle[Land]
定义类型类实例,而不是Vehicle[Land]
的所有类型,但是{{1}可能需要更多成员。)