I cannot get my head around a seemingly easy problem. I have Reply
class, which can contain different response types - Views
:
interface View
data class NiceView(val name: String) : View
class MyReply<T : View>(view: T)
Now, I'd like to write a function that accepts a command and returns an appropriate view based on the command:
fun <T : View> handle(command: Command): Reply<T> {
return Reply(NiceView(""))
}
I can see two issues here:
I get this weird error on the return type Reply<T>
, but this only happens in this toy example and not my production code:
Type argument is not within its bounds.
Expected: View
Found: T
Error when returning Reply()
. This is the thing that is killing my brain and this is what I'm seeing in my production code:
Type mismatch.
Required: T
Found: NiceView
Type mismatch.
Required: Reply<T>
Found: Reply<NiceView>
Type mismatch.
Required: View
Found: NiceView
I did try messing around with co- and contravariance using in
and out
keywords but to no avail. Could someone point me in the right direction here?
fun <T : View> handle(command: Command): Reply<T> {
does not mean a function that "accepts a command and returns an appropriate view." It means "a function that accepts a type of view -- and a command -- and returns a reply of that type of view." The caller of handle
can choose whatever type of View
it wants to get, which is not what you want -- nor what you've implemented, since the user might want something other than NiceView
.
The appropriate type of the handle
function in this code, given your stated goal, is
fun handle(command: Command): Reply<*>