在Kotlin中实例化泛型类型 [英] Instantiating a generic type in Kotlin

查看:869
本文介绍了在Kotlin中实例化泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Kotlin中获取泛型类型的实例的最佳方法是什么?我希望找到以下C#代码的最佳近似(如果不是100%完美):

What's the best way to get an instance of a generic type in Kotlin? I am hoping to find the best (if not 100% perfect) approximation of the following C# code:

public T GetValue<T>() where T : new() {
    return new T();
}

推荐答案

如评论中所述,这可能不是一个好主意.接受() -> T可能是实现此目的的最合理方法.也就是说,以下方法可以实现您正在寻找的东西,即使不一定是最惯用的方式.

As mentioned in comments, this is probably a bad idea. Accepting a () -> T is probably the most reasonable way of achieving this. That said, the following technique will achieve what you're looking for, if not necessarily in the most idiomatic way.

不幸的是,您不能直接实现这一点:Kotlin受到Java祖先的束缚,因此泛型在运行时被删除,这意味着T不再可以直接使用.使用反射和内联函数,您可以解决此问题,

Unfortunately, you can't achieve that directly: Kotlin is hamstrung by its Java ancestry, so generics are erased at run time, meaning T is no longer available to use directly. Using reflection and inline functions, you can work around this, though:

/* Convenience wrapper that allows you to call getValue<Type>() instead of of getValue(Type::class) */
inline fun <reified T: Any> getValue() : T? = getValue(T::class)

/* We have no way to guarantee that an empty constructor exists, so must return T? instead of T */
fun <T: Any> getValue(clazz: KClass<T>) : T? {
    clazz.constructors.forEach { con ->
        if (con.parameters.size == 0) {
            return con.call()
        }
    }
    return null
}

如果我们添加一些示例类,则可以看到,当存在一个空的构造函数时,它将返回一个实例,否则返回null:

If we add some sample classes, you can see that this will return an instance when an empty constructor exists, or null otherwise:

class Foo() {}
class Bar(val label: String) { constructor() : this("bar")}
class Baz(val label: String)

fun main(args: Array<String>) {
    System.out.println("Foo: ${getValue<Foo>()}") // Foo@...
    // No need to specify the type when it can be inferred
    val foo : Foo? = getValue()
    System.out.println("Foo: ${foo}") // Foo@...
    System.out.println("Bar: ${getValue<Bar>()}") // Prints Bar@...
    System.out.println("Baz: ${getValue<Baz>()}") // null
}

这篇关于在Kotlin中实例化泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆