你需要懂的Kotlin开发技巧之五泛型实化-灵析社区

德州安卓

1.泛型实化

先看一个函数,用来判断参数name是否为某种指定泛型类型并执行相对应逻辑:

fun <T> test(name: Any, block: () -> Unit) {
    if (name is T) {
        block()
    }
}

上面的name is T是会直接报错的,或者调用T::class.java也是会报错的,编译器是不支持这种写法的。

为了通过编译器的支持,我们可能会做如下繁琐的封装:

fun test2(name: Any, block: () -> Unit) {
    when(name) {
        is String -> block()
        is Int -> block()
        is Double -> block()
        is GCCheck -> block()
        else -> block()
    }
}

写起来十分麻烦,这个时候泛型实化要登场了:

泛型T加上reified声明并且方法也要加上inline修饰
然后我们就可以优雅写出下面代码:

inline fun <reified T> test(name: Any, block: () -> Unit) {
    if (name is T) {
        block()
    }
}

可以看到,test方法写起来更加简单,请注意reified一定要搭配inline使用。

2.泛型实化应用案例讲解

  • 利用泛型实化更加简单启动Activity 看下平常代码中是怎么启动Activity的:
startActivity(Intent(this, ZygoteActivity::class.java))

又或者我们还可能进行如下封装:

fun Intent.startActivity(activity: AppCompatActivity) {
    activity.startActivity(this)
}

//使用
Intent(this, ZygoteActivity::class.java).startActivity(this)

但是上面写起来都太复杂了,其实上面封装关键都是要拿到目标Activity的Activity::class.java类型,这恰好到了泛型实化发挥的场景了:

定义如下封装:

inline fun <reified T> Activity.startActivity() {
    startActivity(Intent(this, T::class.java))
}

看下优雅的使用:

startActivity<ZygoteActivity>()

有时候我们在进行Activity跳转到还要通过Intent传参,下面我们对这个startActivity扩展函数进一步封装:

inline fun <reified T> Activity.startActivity(block: Intent.() -> Unit = {}) {
    startActivity(Intent(this, T::class.java).apply(block))
}

我们增加一个带接收者的函数类型参数block: Intent.() -> Unit,并给与默认值,看下使用效果:

startActivity<ZygoteActivity> {
    putExtra("key", "value")
    putExtra("key2", 100)
}

使用起来就是这么简单丝滑。

使用起来也是特别的简单丝滑:

阅读量:1656

点赞量:0

收藏量:0