Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin泛函数与逆变_Kotlin_Generics_Contravariance - Fatal编程技术网

Kotlin泛函数与逆变

Kotlin泛函数与逆变,kotlin,generics,contravariance,Kotlin,Generics,Contravariance,我无法解决一个看似简单的问题。我有Reply类,它可以包含不同的响应类型-视图: interface View data class NiceView(val name: String) : View class MyReply<T : View>(view: T) 返回Reply()时出错。这是杀死我大脑的东西,这是我在生产代码中看到的: Type argument is not within its bounds. Expected: View Found: T Type

我无法解决一个看似简单的问题。我有
Reply
类,它可以包含不同的响应类型-
视图

interface View
data class NiceView(val name: String) : View

class MyReply<T : View>(view: T)
  • 返回
    Reply()
    时出错。这是杀死我大脑的东西,这是我在生产代码中看到的:

    Type argument is not within its bounds.
    Expected: View
    Found: T
    
    Type mismatch.
    Required: T
    Found: NiceView
    Type mismatch.
    Required: Reply<T>
    Found: Reply<NiceView>
    Type mismatch.
    Required: View
    Found: NiceView
    
    类型不匹配。
    必填项:T
    发现:NiceView
    类型不匹配。
    所需:答复
    答复:
    类型不匹配。
    必需:视图
    发现:NiceView
    

  • 我确实尝试过使用
    in
    out
    关键字来处理协方差和逆变,但没有效果。有人能给我指出正确的方向吗?

    我无法重现第一个问题,但第二个问题可以通过简单地添加到
    Reply
    类的通用参数或
    handle
    函数的返回值来解决:

    interface View
    data class NiceView(val name: String) : View
    
    class Reply<in T : View>(view: T)
    
    fun <T : View> handle(command: Command): Reply<T> {
        return Reply(NiceView(""))
    }
    
    // OR
    
    class Reply<T : View>(view: T)
    
    fun <T : View> handle(command: Command): Reply<in T> {
        return Reply(NiceView(""))
    }
    
    界面视图
    数据类视图(val名称:字符串):视图
    班级回复(视图:T)
    趣味手柄(command:command):回复{
    返回回复(视图(“”)
    }
    //或
    班级回复(视图:T)
    趣味手柄(command:command):回复{
    返回回复(视图(“”)
    }
    

    中的
    修饰符表示逆变(类似于Java中的“.super T”)

    问题是
    handle()
    表示
    T
    是一个泛型类型,是
    视图的子类。因此,
    T
    可以是
    视图
    的任何子类,但您试图将其强制为
    NiceView
    。这意味着这样的代码不起作用:

    val otherReply: Reply<OtherView> = handle(command)
    
    或者,如果您不关心允许调用方指定视图类型,则根本不需要泛型参数:

    fun handle(command: Command): Reply<View> {
        return Reply(NiceView(""))
    }
    
    fun句柄(command:command):回复{
    返回回复(视图(“”)
    }
    
    有趣的句柄(command:command):Reply{
    并不意味着一个函数“接受一个命令并返回一个适当的视图”。它意味着“一个函数接受一种类型的视图——和一个命令——并返回这种类型的视图。”
    handle
    的调用者可以选择它想要的
    视图的任何类型,这不是您想要的,也不是您已经实现的,因为用户可能想要的不是
    NiceView

    鉴于您的既定目标,此代码中的
    句柄
    函数的适当类型为

    fun handle(command: Command): Reply<*>
    
    fun句柄(command:command):回复
    
    如果你有时间,这是一系列很棒的帖子:太好了!谢谢你的建议!这是我需要atm的地方!:)还有一件事:解释得很好,再次感谢@Louis!这非常有帮助,谢谢!我把我的例子简化了,因为在我的
    Reply
    类中,我还有一个函数,它采用了
    (T)->String
    (一个序列化程序,如果您愿意的话),这不允许我将T指定为逆变:(这是有道理的,谢谢!实际上我会支持你的第二个建议,但由于过于简化,在我的情况下,由于某种原因,它不起作用。我现在实际上返回一个
    other
    。出于某种原因,它会让我指定它为
    other
    fun handle(command: Command): Reply<View> {
        return Reply(NiceView(""))
    }
    
    fun handle(command: Command): Reply<*>