Kotlin中如何让工厂函数传递属性非空的智能转换信息?
在Kotlin中让编译器识别工厂函数返回对象的非空属性
方案一:使用Kotlin Contracts(实验性特性)
Kotlin的Contracts可以向编译器传递额外语义信息,虽然目前仍处于实验阶段,但能解决你的问题。需要添加ExperimentalContracts注解并在函数内定义契约:
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract data class A( val name: String, val number: Int?, ) @OptIn(ExperimentalContracts::class) fun factoryAWithNumber(): A? { contract { // 契约声明:当函数返回非空值时,该返回值的number属性一定不为null returnsNotNull() implies (returnValue.number != null) } val a = A("2", 2) // 实际场景中通过其他方法获取属性值未知的A实例 if (a.number == null) { return null } return a } fun example2(): Int { val a = factoryAWithNumber() ?: return -1 return a.number // 编译器现在能自动识别number非空,无需!!断言 }
方案二:定义专用数据类型(推荐生产环境使用)
如果不想依赖实验性API,更稳妥的方式是定义一个确保number非空的专用数据类型,让工厂函数返回该类型:
data class A( val name: String, val number: Int?, ) // 专门用于存储number非空的A实例 data class ANonNullNumber( val name: String, val number: Int ) fun factoryAWithNumber(): ANonNullNumber? { val a = A("2", 2) // 仅当number非空时,转换为ANonNullNumber返回 return a.number?.let { ANonNullNumber(a.name, it) } } fun example2(): Int { val a = factoryAWithNumber() ?: return -1 return a.number // 类型天然保证非空,编译器完全识别 }
这种方式通过类型系统直接约束属性的非空性,代码可读性更强,也避免了实验性API的潜在风险。
内容的提问来源于stack exchange,提问作者MrKew
相关产品推荐
相关产品推荐

