2016-11-03 21 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[_], который не удовлетворяет ограничениям типа. Есть ли способ сказать компилятору, что у нас есть Class, представляющий Enum.

В Java я бы просто сделал кастинг, но я полагаю, что у Scala есть лучший способ справиться с такими вещами.

КСТАТИ

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") 

Scala 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 
Смежные вопросы