首页 > 解决方案 > 如何使用 Kotlin 在函数中应用多个泛型

问题描述

我正在尝试创建一个函数,该函数将通过解析活动 A 的上下文和活动 B 的类来动画活动 A 到活动 B 之间的转换。我意识到会有一些实例,我想使用来自的序列化数据类来解析信息一项活动。所以我创建了以下函数:

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)
}

但是,这不会编译错误“没有足够的信息来推断参数 U”。我不太明白这是因为我指定类型 U 应该是可序列化的类。如果可能的话,您能否解释一下为什么会发生这种情况以及我该如何解决?

标签: androidkotlingeneric-programming

解决方案


我不太确定你需要在这里使用泛型。

您应该利用多态性并声明以下内容: 为Activity类编写扩展方法,因此您不必将任何上下文作为参数传递。通过使用多态性,让类形成一个是 的东西ActivityMap你的是一个MapStringSerializable你会做得更好。

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

编辑

刚刚测试了代码并尝试调用该函数最终根本无法编译,因为它期望第一个参数恰好Classof Activity

在这种情况下,您可以这样使用新声明:

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<*>作为第一个参数的类型。根本没有任何泛型。


推荐阅读