Hi! Can anyone explain why this code doesn't work?...
# announcements
d
Hi! Can anyone explain why this code doesn't work?
Copy code
typealias F<T> = (T) -> T

fun test() {
  val id: F<*> = { it }
  consume(id)//error here
}

fun <T> consume(v: F<T>) {
}
It looks like all should be fine, but the compiler tells me
Type mismatch: inferred type is Any? but CapturedType(*) was expected
. I thought that the star means "some unknown T", am I wrong?
s
F<*>
is like
(in Nothing) -> out Any?
d
Yeah, I see it in the documentation, but why?
Ok, I can ask another question. What would go wrong if I this compiled.
s
Because you won’t be able to provide an instance of
F
for any given type parameter that satisfies
Function1<in Nothing, out Any?>
In other words, there is no type
T
that is a (sub)class of Nothing and a (super)class of Any?
Your
consume
function is declared in such a way that it cares about the type
T
of
F
, but you give it an instance that is declared to not care about its generic type. A function
fun consume(v: F<*>)
will compile fine.
1
d
In other words, it could compile, but in this case, inside the
consume
, I wouldn't do anything with
v
except default
Any
things (like
toString
). Is this what you mean?
s
Yup.
consume
will actually never call
invoke(..)
on
v
, it will never call any other method that deals with
T
, if
F
had other such methods. Using
v: F<*>
is therefore sufficient.
d
Ok. Thanks a lot
s
E.g. you can call
size
or
hashCode()
or
isEmpty()
on a
MutableList<*>
. None of these functions/properties use the generic parameter
T
. You can even call
get(Int): T
on it and get an
Any?
back safely, but it is kind-of meaningless. You can_not_ call
add(item: T)
on it (since there is no way of proving a value for
item
, since it is of type `Nothing`…