Kotlin泛型函数


Kotlin提供了对泛型函数的支持。

一、泛型函数的使用

在声明函数时允许定义一个或多个泛型形参,泛型形参要用尖括号括起来,整体放在fun与函数名之间。格式如下:

fun  <T,S>  函数名(形参列表):返回值类型{
    //函数体....
}
package test0709

fun <T> copy(from: List<T>, to: MutableList<in T>) {
    for (ele in from) {
        to.add(ele)
    }
}

fun main(args: Array<String>) {
    var strList = listOf("Java", "Kotlin")
    var objList: MutableList<Any> = mutableListOf(2, 1.2, "Android")
    //指定泛型函数的T为String类型
    copy<String>(strList, objList)
    println(objList)
    var intList = listOf(7, 13, 17, 19)
    //不显式指定泛型函数的T的类型,系统推断出T为Int类型
    copy(intList, objList)
    println(objList)
}

输出结果:

[2, 1.2, Android, Java, Kotlin]
[2, 1.2, Android, Java, Kotlin, 7, 13, 17, 19]

声明了泛型函数之后,调用泛型函数时可以在函数名后用尖括号传入实际的类型;也可以在调用泛型函数时不为泛型参数指定实际类型,让系统自动推断出泛型参数的类型。

package test0709

//为泛型形参T扩展方法
fun <T> T.toBookString(): String {
    return "《${this.toString()}》"
}

fun main(args: Array<String>) {
    val a = 2
    //显式指定泛型函数的T为Int类型
    println(a.toBookString<Int>())
    //不显式指定泛型函数的T的类型,系统推断出T为Double类型
    println(3.4.toBookString())

    val str = "Kotlin"
    //不显式指定泛型函数的T的类型,系统推断出T为String类型
    println(str.toBookString())
}

输出结果:

《2》
《3.4》
《Kotlin》

二、具体化类型参数

Kotlin允许在内联函数(使用inline修饰的函数)中使用reified修饰泛型形参,就可以将泛型形参变成一个具体化的类型参数。

val db = listOf("Java", Date(), 103, 2.3, '我')

fun <T> findData(clazz: Class<T>): T? {
    for (ele in db) {
        if (clazz.isInstance(ele)) {
            @Suppress("UNCHECKED_CAST")
            return ele as? T
        }
    }
    return null
}

上面代码定义了一个clazz:Class形参,在调用该函数时必须显式传入一个Class对象。

可以考虑使用reified修饰内联函数的泛型形参,这样可以直接在函数中使用该类型形参,从而避免用户通过函数的参数来传入类型。

//使用reified修饰泛型形参,使之成为具体化的类型参数
inline fun <reified  T> findData():T?{
    for (ele in db) {
        //在函数中直接使用T作为普通类型
        if (ele is T) {
            return ele
        }
    }
    return null
}

对于使用reified修饰的具体化的类型参数,程序可以在函数体内对该参数使用反射。

inline fun <reified T> membersOf() = T::class.members

学海无涯苦作舟

我的微信公众号.jpg


文章作者: HunterArley
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 HunterArley !
评论
  目录