原创

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 (联系作者)
  • 发表时间:2019-12-03 10:40
  • 版权声明:本网站部分内容转载于合作站点或其他站点,但都会注明作/译者和原出处。如有不妥之处,敬请指出。
  • 公众号转载:请在文末添加作者公众号二维码