如何实例化泛型类型的新实例
How to instantiate a new instance of generic type
在 C# 中,您可以对泛型设置新约束以创建泛型参数类型的新实例,Kotlin 中是否有等效项?
现在我的解决方法是:
fun <T> someMethod(class : () -> T) {
val newInstance = class()
}
我正在这样调用 someMethod()
someMethod<MyClass>(::MyClass)
但我想做这样的事情:
fun <T : new> someMethod() {
val newInstance = T()
}
这可能吗?
目前,这是不可能的。您可以为该问题点赞https://youtrack.jetbrains.com/issue/KT-6728 以投票支持添加此功能。
至少,您可以省略泛型类型,因为 Kotlin 可以推断它:
someMethod(::MyClass)
解决方案:
1/ 使用保留参数类型(具体化类型)的内联函数
2/ 在此内联函数中,使用 class 自省(反射 *)调用所需的构造函数
/!\ 内联函数不能在 class 或函数
中 nested/embedded
让我们通过一个简单的例子看看它是如何工作的:
// Here's 2 classes that take one init with one parameter named "param" of type String
//!\ to not put in a class or function
class A(val param: String) {}
class B(val param: String) {}
// Here's the inline function.
// It returns an optional because it could be passed some types that do not own
// a constructor with a param named param of type String
inline fun <reified T> createAnInstance(value: String) : T? {
val paramType = String::class.createType() //<< get createAnInstance param 'value' type
val constructor = T::class.constructors.filter {
it.parameters.size == 1 && it.parameters.filter { //< filter constructors with 1 param
it.name == "param" && it.type == paramType //< filter constructors whose name is "param" && type is 'value' type
}.size != 0
}.firstOrNull() //< get first item or returned list or null
return constructor?.call(value) // instantiate the class with value
}
// Execute. Note that to path the type to the function val/var must be type specified.
val a: A? = createAnInstance("Wow! A new instance of A")
val b: B? = createAnInstance("Wow! A new instance of B")
*) kotlin-reflect.jar 必须包含在项目中
在 Android Studio 中:添加到 build.gradle(模块:app):实现 "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
在 C# 中,您可以对泛型设置新约束以创建泛型参数类型的新实例,Kotlin 中是否有等效项?
现在我的解决方法是:
fun <T> someMethod(class : () -> T) {
val newInstance = class()
}
我正在这样调用 someMethod()
someMethod<MyClass>(::MyClass)
但我想做这样的事情:
fun <T : new> someMethod() {
val newInstance = T()
}
这可能吗?
目前,这是不可能的。您可以为该问题点赞https://youtrack.jetbrains.com/issue/KT-6728 以投票支持添加此功能。
至少,您可以省略泛型类型,因为 Kotlin 可以推断它:
someMethod(::MyClass)
解决方案:
1/ 使用保留参数类型(具体化类型)的内联函数
2/ 在此内联函数中,使用 class 自省(反射 *)调用所需的构造函数 /!\ 内联函数不能在 class 或函数
中 nested/embedded让我们通过一个简单的例子看看它是如何工作的:
// Here's 2 classes that take one init with one parameter named "param" of type String
//!\ to not put in a class or function
class A(val param: String) {}
class B(val param: String) {}
// Here's the inline function.
// It returns an optional because it could be passed some types that do not own
// a constructor with a param named param of type String
inline fun <reified T> createAnInstance(value: String) : T? {
val paramType = String::class.createType() //<< get createAnInstance param 'value' type
val constructor = T::class.constructors.filter {
it.parameters.size == 1 && it.parameters.filter { //< filter constructors with 1 param
it.name == "param" && it.type == paramType //< filter constructors whose name is "param" && type is 'value' type
}.size != 0
}.firstOrNull() //< get first item or returned list or null
return constructor?.call(value) // instantiate the class with value
}
// Execute. Note that to path the type to the function val/var must be type specified.
val a: A? = createAnInstance("Wow! A new instance of A")
val b: B? = createAnInstance("Wow! A new instance of B")
*) kotlin-reflect.jar 必须包含在项目中
在 Android Studio 中:添加到 build.gradle(模块:app):实现 "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"