Как указать класс типов для классов данных в Kotlin - PullRequest
0 голосов
/ 08 апреля 2020

В scala родительский класс, поддерживающий case class, равен product: поэтому мы можем использовать его для полиморфизма в case classe es. Как можно достичь аналогичной цели для data class es в kotlin?

Для парсера yaml, приведенного ниже, мне потребуется замена для dataclass, который представляет разумный родительский класс для всех data classes .

enter image description here

inline fun <reified T: dataclass> loadFromFileDC(path: Path): T  = loadFromFile(path, T::class)

 fun <T: dataclass> loadFromFile(path: Path, cls: KClass<T>) = {
    val mapper = ObjectMapper(YAMLFactory()) // Enable YAML parsing
    mapper.registerModule(KotlinModule()) // Enable Kotlin support

    Files.newBufferedReader(path).use {
        mapper.readValue(it, cls.java)
    }
}

1 Ответ

2 голосов
/ 08 апреля 2020

Если я вас правильно понял, я не думаю, что это возможно в Kotlin. Классы данных - это просто обычные классы. Таким образом, вы можете наследовать его от любого открытого / абстрактного класса, интерфейса или запечатанного класса. Между тем, нет никакого способа наследовать от класса данных, например, заставить все дочерние элементы быть классом данных. И нет никакого наследования, определяющего класс данных c, потому что, как я упоминал, класс данных - это просто обычный класс с предопределенным и предварительно сгенерированным набором методов.

Я думаю, что также стоит подумать об этом: Вам действительно нужно идентифицировать каждый переданный класс как класс данных во время компиляции, и почему он вам действительно нужен?

Если, например, вы хотите применить любой вид полиморфизма, то все, что вы можете использовать, это просто equals / hashCode / toString, потому что функции componenN и copy просто генерируются и не имеют базовых функций, которые они могли бы переопределить.

Поскольку каждый класс может реализовать эти 3 метода. Все, что вы можете сделать, это заставить их реализовать. Например:

interface DataClass {
    override fun equals(other: Any?): Boolean
    override fun hashCode(): Int
    override fun toString(): String
}

data class Impl(val t: Int) : DataClass

В этом случае существует высокая вероятность того, что реализация будет вынуждена быть классом данных, или она будет вынуждена предоставить все 3 необходимых метода. Но это скорее взлом, а не реальное решение, и вы не сможете применить его для сторонних классов, поскольку вы не сможете пометить их этим интерфейсом.

В заключение: я бы порекомендовал думаю, вам действительно нужно знать, это clz из вашего примера data class, или это может быть что угодно. Если да, то вы можете использовать рефлексию.

Пожалуйста, посмотрите это: Есть ли способ идентифицировать Kotlin класс данных из обычного Kotlin класса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...