generics - Kotlin 中的协变函数参数
问题描述
我想实现一个函数,它可以选择接受一个 Activity 类并重定向到它。如果没有提供类,将使用默认值。
在Java中我会做
public void onComplete(@Nullable Class<? extends Activity> redirectTarget) {
if (redirectTarget == null) redirectTarget = DefaultActivity.class;
ContextCompat.startActivity(context, new Intent(context, redirectTarget), null);
}
现在,我在 Kotlin 中尝试了以下操作:
fun <T : Activity> onComplete(redirectTarget: Class<in T> = DefaultActivity::class.java) {
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}
我认为in T
会在参数中接受 T 的任何子类,但在上面的示例中,我收到警告说
Type missmatch.
Expected: Class <in T>
Found: Class<DefaultActivity>
如何实现接受任何 Activity 类的函数?
解决方案
这与方差无关。这是您如何尝试使用泛型的问题。
假设您有一个功能:
fun <T> print(toPrint: T) = println(toPrint.toString())
你可以像这样调用这个函数:
print<Int>(1)
一切都很好。
但是假设String
当用户不想指定 `toPrint' 参数时,您希望有一个默认参数。按照您的方法,您将执行以下操作:
fun <T> print(toPrint: T = "") = println(toPrint.toString())
在一个合法的世界里,如果你调用指定类型而不是参数的函数会发生什么?例如:
print<Int>()
默认参数的类型与调用站点的类型不匹配。
那么如何解决你的问题呢?
事实证明,您甚至不需要通用函数,您可以这样做:
fun onComplete(redirectTarget: Class<out Activity> = DefaultActivity::class.java) {
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}
推荐阅读
- python - 使用 sounddevice numpy 数组执行 fft
- vue.js - 在核心 ui vue.js 的导航栏中有条件地呈现项目的问题
- react-native-ios - 为 ios 反应原生通用链接
- vba - 迭代文件夹中的电子邮件时如何引用电子邮件?
- tensorflow - 无法卸载tensorflow和keras
- java - 使用 GSON 序列化/反序列化简单对象 - 无时区指示器错误
- protractor - 如何使用量角器脚本从小吃店容器中获取价值
- android - 如何在android的工具栏中动态加载图标数组?
- javascript - 无法使用 Vue 打包库 (npm) 加载 CSS 文件
- angular - 带有等待的 Angular Firestore