【问题标题】:Covariant function parameter in KotlinKotlin 中的协变函数参数
【发布时间】:2019-07-12 14:23:52
【问题描述】:

我想实现一个函数,它可以选择接受一个 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 类的函数?

【问题讨论】:

    标签: generics kotlin covariance


    【解决方案1】:

    这与方差无关。这是您尝试使用泛型的方式的问题。

    假设你有一个函数:

    fun <T> print(toPrint: T) = println(toPrint.toString())
    

    你可以这样调用这个函数:

    print<Int>(1)
    

    一切都好。

    但是假设当用户不想指定 `toPrint' 参数时,您希望有一个默认的String 参数。按照你的方法,你会这样做:

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

    【讨论】:

      【解决方案2】:

      试试这个:

      fun onComplete(redirectTarget:Class<out Activity> = DefaultActivity::class.java){
          ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
      }
      

      【讨论】:

        【解决方案3】:

        我现在不知道为什么会这样,但您只需要将其转换为 Class&lt;T&gt;。把你的函数改成这个。

        fun <T : Activity> onComplete(redirectTarget: Class<in T> = DefaultActivity::class.java as Class<T>) {
            ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
        }
        

        我只是在onComplete 输入的末尾添加as Class&lt;T&gt;

        更新:

        你也可以写扩展函数

        fun Class<out Activity>?.onComplete() {
            ContextCompat.startActivity(context, Intent(context, this ?: DefaultActivity::class.java), null)
        }
        

        你可以这样使用它

        MainActivity::class.java.onComplete()
        

        对于默认类

        null.onComplete()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-27
          • 1970-01-01
          • 2019-06-19
          相关资源
          最近更新 更多