2010-10-10 149 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()) 
    } 
}