Reputation: 1915
so i have this code that won't compile.
suspend fun <T> GetContent(call: ApplicationCall) : T {
var requestContent: T? = null
try {
requestContent = call.receive()
}
catch (exception: Exception) {
println(exception)
}
}
The problem is that call.receive()
returns any
so i get an error saying "T? is not a subtype of Any".
So I Read about Any
and the key concept is in the first 2 line of the documentation
"The root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass."
But it creates this paradox where T really does not inherits from Any
because its not a class
but in the other hand it will surly be a class when using it.
I'm new to Kotlin so I guess I just not fully understand the Any
concept or not fully understand something in the Generic concept.
Upvotes: 0
Views: 478
Reputation: 18537
To address the point about Any
:
This is about nullability.
The documentation you found is talking about classes, but not about types; the distinction is subtle but important. (Even in Java, those things aren't quite the same; for example, List
is a class, but List<String>
is a type.)
In Kotlin, nullability is part of the type system. So while Any
is the topmost class (corresponding to Java's Object
), both Any
and Any?
are types: the difference being that only the latter can hold null
. This makes Any
a subtype of Any?
, and Any?
the topmost type.
Your example has the type T?
, which is nullable — and so not a subtype of Any
, which isn't.
However, that's not the only thing going in your question; in the code you quoted, T?
would have to be a supertype of Any
— which it's clearly not. (I'm also puzzled by trying to parameterise only the return value. How is the compiler supposed to infer the actual type of T
in each call?)
Upvotes: 1
Reputation: 838
You probably did Java before, right?
Any
is the Kotlin equivalent to Javas Object
, which means in Kotlin every object implicitly inherits from Any
or in other words Any
can be used as a placeholder for any possible class.
In your case you could try casting your result, I think this will work:
requestContent = call.receive() as T
This line means, you know, that call.receive()
is indeed an Object of class T
or a subclass of it. This will throw an error, if this assumption is false.
// Edit: A clearer example of inheritance.
Take the following example, you have a class Animal
and two subclasses Dog
and Cat
. Your inheritance graph looks like this now:
Animal
/ \
/ \
V V
Dog Cat
So this says: Each cat is an animal and each dog is an animal. But if you have any animal you can't say whether it is a dog or a cat.
In your specific case, Any
is the Animal
class and f.e. Dog
is your T
. So T
does indeed inherit from Any
, but you don't know if it's really a T
or maybe something else, but if you know that in this specific case it is T
, you can cast it.
Upvotes: 1