如何使用 Kotlin 在函数中应用多个泛型
How to apply multiple generics in a function using Kotlin
我正在尝试创建一个函数,通过解析 activity A 的上下文和 class activity B. 我意识到在某些情况下我想使用来自一个 activity 的序列化数据 class 来解析信息。所以我创建了以下函数:
fun <T, U> changeActivity(activityAContext : Context, activityB: Class<T>, anim1 : Int, anim2 : Int, extras : Map<String, Class<U>>?=null)
where T : Activity,
U : Serializable {
val activity = activityAContext as Activity
val intent = Intent(activityAContext , activityB)
if (extras != null) {
for ((k, v) in extras) {
intent.putExtra(k, v)
}
}
activity.overridePendingTransition(anim1, anim2)
finish()
startActivity(intent)
}
但是,这不会编译错误 "Not enough information to infer parameter U"。我不太明白这是因为我指定类型 U 应该是可序列化的 class。如果可能的话,您能否解释一下为什么会发生这种情况以及我该如何解决?
我不太确定您是否需要在此处使用泛型。
您应该利用多态性并声明以下内容:为 Activity
class 编写一个扩展方法,这样您就不必将任何上下文作为参数传递。通过使用多态性,让 class 形成某种东西 ,即 Activity
,而给定的 Map
是 Map
of String
, Serializable
你会非常棒。
fun Activity.changeActivity(newActivityClass: Class<Activity>, enteringAnimation: Int, exitingAnimation: Int, extras: Map<String, Serializable>?=null) {
val intent = Intent(this , newActivityClass)
extras?.let { it.forEach{ pair -> intent.putExtra(pair.key, pair.value)} }
overridePendingTransition(enteringAnimation, exitingAnimation)
finish()
startActivity(intent)
}
您现在可以从任何其他 Activity
使用此扩展功能,如下所示:
changeActivity(DetailActivity::class.java, R.anim.someAnim, R.anim.someOtherAnim, mapOf(Pair("first", myFancySerializableObject)))
无论如何,我在 Kotlin 中设置泛型的方式如下
fun<T: Activity, U: Serializable> myFancyFunction(firstParam: T, second: U) = Unit
编辑
刚刚测试了代码并尝试调用该函数最终根本无法编译,因为它期望 的第一个参数恰好是 Class
的 [=15] =].
在这种情况下,您可以这样使用新声明:
fun <A : Activity> Activity.changeActivity(newActivityClass: Class<A>, enteringAnimation: Int, exitingAnimation: Int, extras: Map<String, Serializable>?=null)
或者通过查看 Intent
的构造函数
public Intent(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
}
您可以使用 Class<*>
作为第一个参数的类型。完全没有任何泛型。
我正在尝试创建一个函数,通过解析 activity A 的上下文和 class activity B. 我意识到在某些情况下我想使用来自一个 activity 的序列化数据 class 来解析信息。所以我创建了以下函数:
fun <T, U> changeActivity(activityAContext : Context, activityB: Class<T>, anim1 : Int, anim2 : Int, extras : Map<String, Class<U>>?=null)
where T : Activity,
U : Serializable {
val activity = activityAContext as Activity
val intent = Intent(activityAContext , activityB)
if (extras != null) {
for ((k, v) in extras) {
intent.putExtra(k, v)
}
}
activity.overridePendingTransition(anim1, anim2)
finish()
startActivity(intent)
}
但是,这不会编译错误 "Not enough information to infer parameter U"。我不太明白这是因为我指定类型 U 应该是可序列化的 class。如果可能的话,您能否解释一下为什么会发生这种情况以及我该如何解决?
我不太确定您是否需要在此处使用泛型。
您应该利用多态性并声明以下内容:为 Activity
class 编写一个扩展方法,这样您就不必将任何上下文作为参数传递。通过使用多态性,让 class 形成某种东西 ,即 Activity
,而给定的 Map
是 Map
of String
, Serializable
你会非常棒。
fun Activity.changeActivity(newActivityClass: Class<Activity>, enteringAnimation: Int, exitingAnimation: Int, extras: Map<String, Serializable>?=null) {
val intent = Intent(this , newActivityClass)
extras?.let { it.forEach{ pair -> intent.putExtra(pair.key, pair.value)} }
overridePendingTransition(enteringAnimation, exitingAnimation)
finish()
startActivity(intent)
}
您现在可以从任何其他 Activity
使用此扩展功能,如下所示:
changeActivity(DetailActivity::class.java, R.anim.someAnim, R.anim.someOtherAnim, mapOf(Pair("first", myFancySerializableObject)))
无论如何,我在 Kotlin 中设置泛型的方式如下
fun<T: Activity, U: Serializable> myFancyFunction(firstParam: T, second: U) = Unit
编辑
刚刚测试了代码并尝试调用该函数最终根本无法编译,因为它期望 的第一个参数恰好是 Class
的 [=15] =].
在这种情况下,您可以这样使用新声明:
fun <A : Activity> Activity.changeActivity(newActivityClass: Class<A>, enteringAnimation: Int, exitingAnimation: Int, extras: Map<String, Serializable>?=null)
或者通过查看 Intent
public Intent(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
}
您可以使用 Class<*>
作为第一个参数的类型。完全没有任何泛型。