先看一个函数,用来判断参数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使用。
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