在Scala中,是否可以实例化通用类型T的对象? [英] In Scala, is it possible to instantiate an object of generic type T?
问题描述
在Scala中,即使解决方案不是很好,也可以实例化/创建泛型T的新对象吗?可以使用反射来实现吗?
In Scala, even if the solution is not elegant, is it possible to instantiate/create a new object of a generic type T? Is it possible to achieve this using reflection?
例如,我对以下内容感兴趣:
For example, I am interested in something like the following:
case class Person(name: String, age: Int)
假设我要执行以下操作来创建类型为Person的对象:
Let's say I wanted to do the following to create an object of type Person:
def createObject[T](fieldValues: Seq[Any]): T = {
... T(fieldValues)
}
val person = createObject[Person](Seq("Bob", 20))
推荐答案
从技术上讲,可以使用反射.例如,您可以使用ClassTag
捕获类型为T的运行时类,然后找到合适的构造函数并创建实例:
Technically speaking it's possible using reflection. You could for example catch runtime class of type T using ClassTag
then find proper constructor and create instance:
def createObject[T](fieldValues: Seq[Any])(implicit ct: ClassTag[T]): Option[T] = {
//we lookup for matching constructor using arguments count, you might also consider checking types
ct.runtimeClass.getConstructors.find(_.getParameterCount == fieldValues.size)
.flatMap {constructor =>
Try(constructor.newInstance(fieldValues: _*).asInstanceOf[T]).toOption
}
}
createObject[Person](Seq("Bob", 20)) //Some(Person("Bob", 20))
createObject[Person](Seq(20, 10)) //None
如果没有构造函数匹配的参数,则该函数将无法返回None
.
In case there's no constructor matching parameters, that function fails returning None
.
它应该可以工作,但是最好避免这种方法,因为这样会失去所有类型的安全性.
It should work, but it'd be best if you can avoid this approach because you lose all type safety.
这篇关于在Scala中,是否可以实例化通用类型T的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!