Общее ограничение как список типов?Или утка во время компиляции? - PullRequest
0 голосов
/ 12 марта 2019

Следующий минимальный пример хорошо показывает мою проблему, я надеюсь:

data class OneThing(val x: Int, val y: Int, val foo: String)
data class ASimilarThing(val x: Int, val y: Int, val bar: String)

fun <THING> process(thing: THING) {
    println(thing.x)
    println(thing.y)
}

fun main() {
    val oneThing = OneThing(1, 2, "hi")
    val aSimilarThing = ASimilarThing(3, 4, "ho")
    process(oneThing)
    process(aSimilarThing)
}

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

Однако вышеприведенное не компилируется. ( В C ++ это возможно. )

Есть ли способ заставить process работать? В идеале я ищу что-то вроде

fun <THING: [OneThing, ASimilarThing]> process(thing: THING) { ... }

Но такого синтаксиса не существует.

Есть еще идеи? :)

1 Ответ

2 голосов
/ 12 марта 2019

Kotlin like Java - статически типизированный объектно-ориентированный язык.Поэтому вам нужно будет предоставить общий супертип, объявляющий свойства x и y.

. Поскольку это не тот случай, вы не можете добиться утки, как вам нравится.THING имеет супертип Any?, поэтому x и y недоступны.

Вы можете обойти свою проблему, используя оболочку или делегат:

sealed class Thing {
    abstract val x: Int
    abstract val y: Int
}
class ASimilar(
    delegate: orig.OneThing
): Thing() {
    override val x get() = delegate.x
    override val y get() = delegate.y
}
class ASimilarThing(
    delegate: orig.ASimilarThing
): Thing() {
    override val x get() = delegate.x
    override val y get() = delegate.y
}


fun process(thing: Thing) {
    println(thing.x)
    println(thing.y)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...