2016-09-02 3 views
0

У меня есть общий метод, который имеет тип общего типа T, который является подклассом MyClass. Внутри этого метода я хочу создать новый экземпляр T, как я могу это сделать?Необычный конкретный класс общий метод в scala

Это не работает (из-за типа стирания):

object Demo extends App { 
    def myMethod[T <: MyClass](): Unit = { 
     val t = new T // gives error: class type required by T found 
    } 
    myMethod[MySubclassA]() 
} 


abstract class MyClass 
class MySubclassA extends MyClass 
class MySubclassB extends MyClass 

ответ

2

Это не работает, но не (в первую очередь), так как стирания типа, но поскольку ваше определение должно иметь смысл для всех T, которые удовлетворяют ограничениям типа, а new T - нет. Например. T может быть MyClass или абстрактный подкласс, или подкласс без конструктора параметра меньше или черты (черты могут расширить классы), или ...

Если ошибка выполнения достаточно хорошо, вы можете пойти с Сергеем Решение Лагутина. Но более разумным для большинства случаев было бы каким-то образом создать T до myMethod. Возможно, как неявный аргумент, например.

class Factory[T](f:() => T) { 
    def make(): T = f() 
} 
object Factory { 
    implicit val MySubclassAFactory = 
    new Factory(() => new MySubclassA) 
    implicit val MySubclassBFactory = 
    new Factory(() => new MySubclassB) 
} 
def myMethod[T <: MyClass](implicit factory: Factory[T]): Unit = { 
    val t = factory.make() 
    ... 
} 

myMethod[MySubclassA] // works 
myMethod[MyClass] // compilation error 
myMethod[ASubclassForWhichFactoryIsNotDefined] // compilation error 
+0

Пропустив неявный аргумент вы имеете в виду: определение функции MyMethod [T <: MyClass]() (неявный т: Т) ' – Samar

+0

Нет, я добавил код, чтобы показать, что я имел в виду. –

1

Вы можете использовать ClassTag для достижения своей цели:

def myMethod[T <: MyClass : ClassTag]: T = 
    implicitly[ClassTag[T]].runtimeClass.newInstance().asInstanceOf[T] 

println(myMethod[MySubclassA]) // [email protected] 
println(myMethod[MySubclassB]) // [email protected] 
Смежные вопросы