https://kotlinlang.org logo
#getting-started
Title
# getting-started
s

Stylianos Gakis

01/16/2023, 11:15 AM
When I got an interface say like this
Copy code
interface Binding<T> {
    var value: T
}
And later I have a function which takes a
Binding<String?>
like this
fun foo(asd: Binding<String?>) {}
If on a function, I got an instance of
Binding<String>
, I am unable to pass it since it sees
Binding<String>
and
Binding<String?>
as different types. Changing my interface
Binding
to take in
out T
instead fixes this problem on the call site, but gives me an error on
val value: T
as it tells me that it is delcared as
out
but it occurs in
invariant
position in type T. If it were a
val value: T
it’d work, but it’s a
var
now and I can’t change that. Right now what I am doing, is that in call sites, if I got a
Binding<T>
I convert it into a
Binding<T?>
manually to pass it in. Is this the best I can do in this case?
s

Sam

01/16/2023, 11:23 AM
What do you mean by “convert manually”? If it’s a
var
, it has to be invariant. Can you make a superinterface for those places where you want covariance? e.g.
Copy code
interface Binding<T>: ReadOnlyBinding<T> {
    override var value: T
}

interface ReadOnlyBinding<out T> {
    val value: T
}
🙏 1
g

Gleb Minaev

01/18/2023, 12:01 PM
Alternatively, you can write
Copy code
interface Binding<T> {
    var value: T
}

fun foo(asd: Binding<out String?>) {
    val str: String? = asd.value // compiles well
//    asd.value = null // does not compile as expected of covariant declaration
}
without any need in additional interfaces.
s

Stylianos Gakis

01/18/2023, 12:22 PM
Right, you can specify
out
just in a function as well that’s true. Seems to work in the sample I was trying it on, at least the IDE isn’t complaining. Thanks for the idea, might try it out and see how it behaves.
6 Views