You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请详细解释这段Kotlin代码中out T的作用及泛型实现

Kotlin中ResultWrapper<out T>里out T的作用详解

直白说:out T是Kotlin里声明协变类型参数的关键字,核心作用是让泛型类支持「子类型向上兼容」,同时限制这个泛型参数只能作为「输出」(比如只读属性、返回值),不能当「输入」(比如方法参数、可变属性的setter)。

结合你给出的密封类代码,拆解逻辑:

1. 密封类层级的协变规则

sealed class ResultWrapper<out T> 里的out,给整个ResultWrapper家族定下协变规则:如果A是B的子类,那ResultWrapper<A>可以直接当作ResultWrapper<B>来用。

举个实际场景:假设你有个返回ResultWrapper<String>的接口,想把结果赋值给ResultWrapper<Any>类型的变量——如果没有out,这会直接报错;加了out,这个赋值就合法,因为String是Any的子类,协变允许这种向上转型。

2. Success类的协变适配

data class Success<out T>(val value: T): ResultWrapper<T>() 里的out,是因为Success类的核心属性value是只读的(val),属于「输出」,完全符合协变要求。这样当你拿到一个ResultWrapper<Any>实例时,它可能是Success<String>、Success<Int>等,你可以安全读取value并当作Any类型使用,不会有类型安全问题。

3. 错误类型用ResultWrapper<Nothing>的原因

GenericError和NetworkError都继承自ResultWrapper<Nothing>,这是因为Nothing是Kotlin里所有类型的子类。结合协变规则,ResultWrapper<Nothing>可以赋值给任何ResultWrapper<T>类型——不管你期望的返回类型是User、String还是其他,错误结果都能直接适配,不用为每个错误单独定义泛型版本,大幅简化代码。

比如你写了一个返回ResultWrapper<User>的接口,出现网络错误时直接返回NetworkError就行,不用特意写ResultWrapper<User>的错误实现,因为ResultWrapper<Nothing>能自动兼容ResultWrapper<User>。

没有out会怎样?

如果去掉所有out,ResultWrapper就是不变泛型类,ResultWrapper<User>不能赋值给ResultWrapper<Any>,错误类型也无法适配不同的泛型返回值,你得为每个可能的返回类型定义对应的错误子类,代码会冗余且不灵活。

内容的提问来源于stack exchange,提问作者Hack123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:28:16