2010-10-10 106 views
2

我在函数中指定枚举值类型(实例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

相关问题在scala用户邮件列表中:http://scala-programming-language.1934581.n4.nabble.com/Making-combinations-td3017320.html – 2010-10-28 19:31:15

+0

您的解决方案版本1似乎在scala中工作正常2.11.7 – qed 2016-02-11 19:27:30

回答

1

编辑:

看起来像你只需要帮助的类型inferencer一点得到你的第一个解决方案的工作:

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) 
    } 
} 
+0

这个解决方案的问题是'V'与'E.Value'不兼容 - 并且如果我想在内部处理器中执行某些类似于'enum.values.find {_ == value}'的操作,它将不会受到类型检查。 – andreypopp 2010-10-18 18:26:10

+0

我更新了我的答案 - 现在应该涵盖这个用例。 – 2010-10-19 16:12:52

1

另一个潜在的解决方案是定义一个mixin,它允许你创建一个“处理器”特定枚举实例:

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()) 
    } 
}