指定枚举值类型的问题

时间:2010-10-10 10:28:15

标签: scala

我在为函数中的枚举值(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?虽然这似乎是不可能的,因为类型不能依赖于具体的值,也许有一些技巧可以达到预期的效果而不需要额外的样板。

2 个答案:

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