Почему Kotlin не может отличить между интерфейсом и родовым типом, который получен из него?

S-K' спросил: 12 мая 2018 в 03:39 в: kotlin

У меня есть следующий класс:

abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() { 
    open fun initViewIntent(): I {
        return object : ViewIntent{} // type mismatch on this line
    }
}

Я получаю сообщение о предварительной компиляции:

Type mismatch
Required: I
Found: <S, I>

Чтобы исправить эту предварительную -compilation error Я передаю объект ViewIntent в I:

abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() { 
    open fun initViewIntent(): I {
        @Suppress("UNCHECKED_CAST")
        return object : ViewIntent{} as I
    }
}

Но почему Kotlin не может обнаружить, что I должен быть получен из ViewIntent и smart cast it?

2 ответа

Есть решение
Raymond Arteaga ответил: 12 мая 2018 в 04:32

Просто потому, что "я" НЕ обязательно выводится из ViewIntent, но точно из класса ViewIntent.

Вы можете исправить это следующим образом:

abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() { 
    open fun initViewIntent(): ViewIntent {
        return object : ViewIntent{} 
    }
}

Выполнение это ваш путь действительно небезопасный. Чтобы понять, почему, я думаю, вы должны начать читать это:

https://blog.kotlin-academy.com/kotlin-generics-variance -modifiers-36b82c7caa39 https://kotlinlang.org/docs/reference/generics.html https://proandroiddev.com/understanding-generics-and-variance-in -kotlin-714c14564c47

Egor Neliuba ответил: 12 мая 2018 в 04:34

Это потому, что ViewIntent не I. Пример:

class MyViewIntent : ViewIntentclass MyPresenterActivity : PresenterActivity<..., MyViewIntent>() {
    // inherited from PresenterActivity
    open fun initViewIntent(): ViewIntent {
        return object : ViewIntent{} as MyViewIntent // you see where this breaks
    }
}