Я хочу реализовать функцию, которая необязательно принимает класс Activity и перенаправляет на него. Если класс не указан, будет использоваться значение по умолчанию.
В Java я бы сделал
public void onComplete(@Nullable Class<? extends Activity> redirectTarget) {
if (redirectTarget == null) redirectTarget = DefaultActivity.class;
ContextCompat.startActivity(context, new Intent(context, redirectTarget), null);
}
Теперь я попробовал следующее в Котлине:
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)
}
я не знаю, почему это так, но вам просто нужно передать это Class<T>
. измените свою функцию на это.
fun <T : Activity> onComplete(redirectTarget: Class<in T> = DefaultActivity::class.java as Class<T>) {
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}
я просто добавляю as Class<T>
в конце onComplete
входных данных
вы также можете написать функцию расширения
fun Class<out Activity>?.onComplete() {
ContextCompat.startActivity(context, Intent(context, this ?: DefaultActivity::class.java), null)
}
и вы можете использовать его так
MainActivity::class.java.onComplete()
и для класса по умолчанию
null.onComplete()
Попробуй это:
fun onComplete(redirectTarget:Class<out Activity> = DefaultActivity::class.java){
ContextCompat.startActivity(context, Intent(context, redirectTarget), null)
}