假设我有一个Message班和一个Channel<T : Message>班.

现在,为什么我不能在没有未经判断的施法警告的情况下使用Channel<out Message>Channel<Message>的法术呢?

既然Channel<out Message只能包含Message类型的对象或Message类型的子类,那么这个强制转换不应该总是安全的吗?

推荐答案

不,这就是证据.

class Channel<T : Message> {
  fun send(t: T)
  fun receive(): T
}
class Apple : Message()
class AppleChannel : Channel<Apple>() {
  ...
}

val appleChannel = AppleChannel()
val outMessageChannel: Channel<out Message> = appleChannel // MUST WORK
val messageChannel: Channel<Message> = outMessageChannel 
   // you say this should work, but...
messageChannel.send(Orange()) 
   // sending orange on a channel that only knows how to send apples!  
   // Error!

在这种情况下,唯一一致的做法是不允许将Channel<out Message>转换为Channel<Message>.

如果将其定义为Channel<out T: Message>,则这将是安全的,但try 定义send将导致错误.

Kotlin相关问答推荐

最好的方法来创建一个 map 在kotlin从两个列表

在Webflux应用程序中通过kotlin协程启动fire and forget job

可以从背景图像中点击图标吗?

Kotlin扩展函数未调用Hibernate/JPA中的重写函数

JobIntentService 被销毁,当应用程序被销毁时

Kotlin 中多个 init 块的用例?

将 Gradle 子元素与 Kotlin 多平台一起使用

来自类型参数的属性的自定义 getter

`DataBindingUtil` 中的 `bind`、`inflate` 和 `setContentView` 有什么区别

变量后的Android问号

将 @Component.Builder 与构造函数参数一起使用

Android Studio 和 Kotlin:Unresolved reference: also

将多个 Kotlin 流合并到一个列表中,而无需等待第一个值

如何将命令行参数传递给Gradle Kotlin DSL

如何将map函数应用于Kotlin中的数组并更改其值?

是否在Kotlin中重写enum toString()?

Kotlin中具有多个参数的绑定适配器

Kotlin中保留的关键字是什么?

如何在Kotlin中使方法param可变?

Kotlin中的函数接口