https://kotlinlang.org logo
#announcements
Title
# announcements
d

Derek Peirce

11/16/2019, 9:38 PM
I have a covariance/contravariance issue.
Copy code
class Appender<out T1>(private val value: T1) {
    fun <T2 : T3, T3> addTo(list: List<T2>): List<T3> = (list + value) as List<T3>
}

fun main() {
    val appender = Appender(2.0)
    val list = listOf(1)
    val combined = appender.addTo<Int, Number>(list)
    println(combined)
}
Suppose I have an
Appender
class that creates a list by appending values to another list. The above code works for this, but: - It's necessary to specify
T3
- There's no guarantee here that
T3
is a supertype of
T1
, just
T2
From what I've seen, I can specify `T3 : T1, but not my aim of
T1 : T3
. Additionally, I would like
T3
to be inferred automatically, similar to how
listOf(1) + listOf(2.0)
gives
List<Any>
by default, but can be specified as
List<Number>
without issue. In particular, I would like
Appender<Nothing>
to return
List<T2>
without having to specify
addTo<T2, T2>
. (Obviously,
Appender<Nothing>
wouldn't be useful, but my use-case has other side effects. The method is also used to implement an interface, so converting it to a static extension method as is done for
List + List
isn't an option.) Does anyone know how this problem could be solved, or at least simplified, in Kotlin?
k

Kroppeb

11/17/2019, 12:10 AM
Extension function seems to do the trick
Copy code
class Appender<out T> constructor(val item:T){

}

fun <T>Appender<T>.addTo(lst:List<T>) = lst + item


fun main() {
    val appender = Appender(2.0)
    val list = listOf(1)
    val combined:List<Number> = appender.addTo(list)
    println(combined)
}
d

Derek Peirce

11/17/2019, 2:53 AM
As I already stated, the method in my case is used to implement an interface, so it may not be a static extension method.
m

molikuner

11/17/2019, 8:29 PM
As far as I understand your problem, your running against sth like: https://stackoverflow.com/questions/43790137 So basically I think this isn’t really solvable in Kotlin.
2 Views