синтаксис для обобщенной c -параметрической переменной / константы - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь создать Map, содержащий общие c -параметризованные типы. Например:

abstract class Foo {
 companion object {
  val fooInjectors = HashMap<Class<T: Foo>, Injector<T: Foo>>()
 }
}

Идея состоит в том, чтобы fooInjectors (который был бы static в Java или companion object в Kotlin) содержал кеш подклассов Foo и соответствующие им Injector.

К сожалению, я не могу это скомпилировать. Я был бы очень признателен, если бы кто-нибудь помог мне разобраться с синтаксисом для этого!

1 Ответ

2 голосов
/ 17 июня 2020

Насколько мне известно, вы пытаетесь сделать то, что невозможно в Kotlin. Сопутствующий объект является одноэлементным, и нет смысла создавать одноэлементный объект, так как больше не будет создаваться никаких объектов, поэтому общие c типы не имеют значения. Таким образом, вы не можете генерировать объявленное свойство, потому что оно находится в сопутствующем объекте.

Однако один из способов заставить это работать - использовать функцию поддержки. Эта функция поддержки должна аннотироваться отклонением от места объявления .

Это просто означает, что мы сообщаем компилятору, что мы возвращаем только тип T из метода (и не потребляем). Это позволяет нам при необходимости использовать подтипы и супертип T. Это называется ковариацией.

Вы можете посмотреть документацию, чтобы понять это дальше - https://kotlinlang.org/docs/reference/generics.html#declaration -site-variance

Вот что я имел в виду.

interface Injector<T>
class InjectorImpl<T> : Injector<T>

abstract class Foo {
    companion object {
        val fooInjectors = createMap<Foo>()

        private fun <T> createMap(): HashMap<Class<out T>, Injector<out T>> {
            return HashMap()
        }
    }
}

class Bar: Foo()

object Runner {
    @JvmStatic
    fun main(args: Array<String>) {
        Foo.fooInjectors[Bar::class.java] = InjectorImpl<Bar>()
        Foo.fooInjectors[Foo::class.java] = InjectorImpl<Bar>()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...