具体化类型参数

有时我们需要访问传入给参数的类型:

fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
    var p = parent
    while (p != null && !clazz.isInstance(p)) {
        p = p?.parent
    }
    @Suppress("UNCHECKED_CAST")
    return p as T
}

在这里,我们沿着继承树,使用反射判断一个节点是不是特定类型。这没什么不妥,但是实现过程不优雅。

myTree.findParentOfType(MyTreeNodeType::class.java)

我们真正想要的仅仅是简单的传递一个类型给这个函数,比如:

myTree.findParentOfType<MyTreeNodeType>()

为了实现这个功能,inline函数支持具体化类型参数,所以我们可以这样写:

inline fun <reified T> TreeNode.findParentOfType(): T? {
    var p = parent
    while (p != null && p !is T) {
        p = p?.parent
    }
    return p as T
}

我们使用reified修饰符限定类型参数,那么其在函数内部就是可访问的,就像一个正常的类一样。因为这个函数是内联的,不需要使用反射,正常的操作符比如!is和as都可以使用。同样的,我们可以按照上述的方式调用这个方法。

myTree.findParentOfType<MyTreeNodeType>()

尽管反射在很多情况下不是必要的,我们依然可以在使用具体化参数的地方使用反射。

inline fun <reified T> membersOf() = T::class.members
fun main(s: Array<String>) {
    println(membersOf<StringBuilder>().joinToString("\n"))
}

正常 的函数(未被标记为inline)不能使用具体化参数。不具备运行时展现形式(比如一个非reified的类型参数或虚构的类型比如Nothing)的类型不能被用作具体化类型参数表达式。

results matching ""

    No results matching ""