我在为函数中的枚举值(scala.Enumeration
的实例)指定类型时遇到问题。这最初源于我需要序列化数据库中的枚举对象,但我在以下示例中提取了有问题的代码:
object EnumerationTypes {
class EnumerationProcessor[E <: Enumeration](enum: E, value: E#Value) {
def process: E#Value = {
value
}
}
object Enum extends Enumeration {
type EnumValue = Value
val a = Value(1, "a")
val b = Value(2, "b")
}
case class Obj(val flag: Enum.EnumValue)
def main(args: Array[String]) {
val processor = new EnumerationProcessor(Enum, Enum.a)
val obj = Obj(processor.process)
}
}
导致以下编译错误:
error: type mismatch;
found : EnumerationTypes.Enum#Value
required: EnumerationTypes.Enum.EnumValue
val obj = Obj(processor.process)
虽然这样可行但是:
object EnumerationTypesOk {
class EnumerationProcessor[E <: Enumeration](enum: E, value: E#Value) {
def process: E#Value = {
value
}
}
class Enum extends Enumeration {
type EnumValue = Value
val a = Value(1, "a")
val b = Value(2, "b")
}
object Enum extends Enum
case class Obj(val flag: Enum#EnumValue)
def main(args: Array[String]) {
val processor = new EnumerationProcessor(Enum, Enum.a)
val obj = Obj(processor.process)
}
}
但我不希望我的代码看起来像这样(首先定义类,然后定义它的单例实例)。
问题是:我如何使value
类型完全属于enum.EnumValue
?虽然这似乎是不可能的,因为类型不能依赖于具体的值,也许有一些技巧可以达到预期的效果而不需要额外的样板。
答案 0 :(得分:1)
修改强>
看起来您只需要帮助类型推断器以使您的第一个解决方案正常工作:
val processor = new EnumerationProcessor[Enum.type](Enum, Enum.a)
希望比我更聪明的人会来解释原因。
在OP澄清评论之前:
object EnumerationTypes {
class EnumerationProcessor[E <: Enumeration, V <: E#Value](enum: E, value: V) {
def process: V = {
value
}
}
object Enum extends Enumeration {
type EnumValue = Value
val a = Value(1, "a")
val b = Value(2, "b")
}
case class Obj(val flag: Enum.EnumValue)
def main(args: Array[String]) {
val processor = new EnumerationProcessor(Enum, Enum.a)
val obj = Obj(processor.process)
}
}
答案 1 :(得分:1)
另一个可能的解决方案是定义一个mixin,允许您为特定的Enumeration实例创建一个“处理器”:
object EnumerationTypes {
trait EnumerationProcessor { self: Enumeration =>
def processor(value: self.Value): () => self.Value = () => {
value
}
}
object Enum extends Enumeration with EnumerationProcessor {
type EnumValue = Value
val a = Value(1, "a")
val b = Value(2, "b")
}
case class Obj(val flag: Enum.EnumValue)
def main(args: Array[String]) {
val processor = Enum.processor(Enum.a)
val obj = Obj(processor())
}
}