Kotlin的Reified类型:怎样在函数内使用这一类型(KAD 14)
时间:Mar 2, 2017
原文链接:https://antonioleiva.com/reified-types-kotlin/
对于Java开发者来说,最懊恼的限制之一是,在用泛型时不能够直接地使用类型。
通常解决方法是以函数参数形式传递类,这使得代码更复杂且缺乏吸引力。
在Kotlin中,多亏有了inline函数(我们已经讨论过),我们可以用reified类型使我们能够在函数内使用它们。
为什么会如此?你会明白的,你会喜欢它的。
Reified 类型
如我早前的论述,以reified修饰类型后,我们就能够在函数内部使用相关类型了。
重要的是,使用内联函数后,在其运行地方需要替换代码来获得类型。事实上由于Java虚拟机的限制,类型不能使用,而是跳过限制的“诡计”。
引导到一个活动(Activity)
这是最典型的Android应用案例。
在Java中,我们调用startActivity时,我们需要以参数形式指明目的类。
在Kotlin中,我们能够通过添加类型传递给函数来简化这个操作:
1 inline fun <reified T : Activity> Activity.startActivity() { 2 startActivity(Intent(this, T::class.java)) 3 }
现在,引导一个Activity就可以如此简单:
1 startActivity<DetailActivity>()
FindView类型转换
部分Android开发人员使用Java十分有益的方式是用泛型通过变量赋值结果返回对象类型。
在Java中,你可以产生这样的一个函数:
1 public <T extends View> T findView(Activity activity, int id) { 2 return (T) activity.findViewById(id); 3 }
然后用它返回对象类型:
1 TextView textView = Utils.findView(activity, R.id.welcomeMessage);
在Kotlin中,做法有些类似,但是由于有了扩展函数就更加容易:
1 fun <T : View> Activity.findView(id: Int) = findViewById(id) as T 2 3 val textView = activity.findView<TextView>(R.id.welcomeMessage)
但是,你会发现这种情况,由于没有访问T类型,编译器都不能确定有效类型,所以编译器会给出警告。
用了reified类型,就可以避免这种情况:
1 inline fun <reified T : View> Activity.findView(id: Int) = findViewById(id) as T
结论
用reified类型,你能够做一些在Java中不可能实现的事情,甚至可以做一些更安全的函数。
现在,你可以避免将类的类型作为自变量传递给你的函数了。
此外,由于有了扩展函数,你能够在框架(如Android)上创建新函数了。在Android的API中有些部分已经使用这个方法(如startActivity方法)。
如果你要开始用Kotlin开发你自己的APP,我建议你阅读免费指南和Android开发者的Kotlin书。