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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:12:15