【问题标题】:Function returns generic class of base interface - Type mismatch函数返回基接口的泛型类 - 类型不匹配
【发布时间】:2019-11-29 16:56:13
【问题描述】:

倒数第二行没有编译,但最后一行编译正常:

  • 是什么原因(他们好像和我一样)?
  • 我可以进行哪些更改以使return if(true) m1 else m2 能够编译?

编译错误:

类型不匹配:推断类型为 Hold<HelloMsg> 但应为 Hold<Msg>

interface Msg
class HelloMsg: Msg
class ByeMsg: Msg
class Hold<T: Msg>(val msg: T)

fun test(): Hold<Msg> {
  val m1 = Hold(HelloMsg())
  val m2 = Hold(ByeMsg())
  return if(true) m1 else m2                             //DOESN'T COMPILE
  return if(true) Hold(HelloMsg()) else Hold(ByeMsg())   //COMPILES
}

【问题讨论】:

  • 我想我已经有了第二个问题的答案:fun test(): Hold&lt;out Msg&gt; { ... }

标签: generics kotlin


【解决方案1】:

我可以更改什么以使 return if(true) m1 else m2 能够编译?

制作Holdcovariant:class Hold&lt;out T: Msg&gt;(val msg: T)。那么Hold&lt;HelloMsg&gt;Hold&lt;ByeMsg&gt; 都将是Hold&lt;Msg&gt; 的子类型。

我想我已经有了第二个问题的答案:fun test(): Hold&lt;out Msg&gt; { ... }

是的,这也有效,但更本地化。 class Hold&lt;out T&gt; 基本上等同于所有使用标记为outHold

是什么原因(他们好像和我一样)?

if(true) m1 else m2 的情况下,m1m2 的类型已经被它们的声明所固定,并且不同于Hold&lt;Msg&gt;

if(true) Hold(HelloMsg()) else Hold(ByeMsg()) 中,编译器在输入Hold(HelloMsg()) 时知道它必须是Hold&lt;Msg&gt;。所以它推断类型参数为Hold&lt;Msg&gt;(HelloMsg())。与其他分支相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多