2016-11-03 182 views
0

我有下面的類:Scala的泛型類[_]參數

class MyClass[T <: Enum[T]](val clazz: Class[T]){ 
    def dummy = println(clazz.toString) 
} 

和這應該創建MyClass對象下面的方法:

def createMyClass(clazz: Class[_]) = 
    if(clazz.isEnum) 
    new MyClass(clazz) //compile error is here 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

但它拒絕編譯。實際上,我們通過了不符合類型邊界的Class[_]的對象。有沒有辦法告訴編譯器我們實際上有一個代表EnumClass。在Java中,我只是做投射,但我想斯卡拉有一些更好的方法來處理這種事情。

BTW,

new MyClass(clazz.asInstanceOf[Class[Enum[_]]]) 

無法正常工作或

我不能改變方法的簽名。

回答

1

我不能改變方法的簽名。

可以做,如果有必要,使用一個存在的類型

def createMyClass(clazz: Class[_]) = 
    if(clazz.isEnum) 
    new MyClass(clazz.asInstanceOf[Class[T] forSome { type T <: Enum[T] }]) 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

但是,你應該仔細考慮,如果它實際上是必要的。 asInstanceOf應該,如果不總是最後的手段,然後接近它。

+0

非常好,非常感謝! – stella

1

聲明的方法與T同類型的限制,然後它會編譯

def createMyClass[T <: Enum[T]](clazz: Class[T]) = 
    if(clazz.isEnum) new MyClass(clazz) 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

斯卡拉REPL

scala> class MyClass[T <: Enum[T]](val clazz: Class[T]){ 
    def dummy = println(clazz.toString) 
    } 
defined class MyClass 

scala> def createMyClass[T <: Enum[T]](clazz: Class[T]) = 
    if(clazz.isEnum) 
     new MyClass(clazz) else throw new IllegalArgumentException(s"$clazz is not an enum") 
defined function createMyClass