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

关于Kotlin可空类型扩展函数与智能转换差异的技术疑问

为什么标准库isNullOrBlank()和自定义nullOrBlank()调用后类型推断不同?
  • 核心原因:标准库函数用了Kotlin契约(Contract)
    Kotlin的契约机制允许函数向编译器传递额外的类型推断逻辑。标准库中的isNullOrBlank()函数带有@Contract注解,明确告知编译器:如果该函数返回false,那么调用它的String?类型接收者一定不为null。

    标准库的简化实现逻辑如下:

    @kotlin.internal.InlineOnly
    @Contract("null -> true")
    public inline fun CharSequence?.isNullOrBlank(): Boolean {
        return this == null || this.isBlank()
    }
    

    当你写if (!input.isNullOrBlank())时,编译器通过契约信息直接推断出此时input已转为非空的String类型,因此可以直接访问input.length,无需安全调用或非空断言。

  • 自定义函数缺少契约注解
    你自己编写的nullOrBlank()函数默认没有添加契约注解,即便逻辑和标准库完全一致,编译器也无法从函数返回值推断出接收者的非空性。此时编译器仍将input视为String?类型,所以访问input.length时会触发编译错误,要求你使用?.或!!.。

    若想让自定义函数实现同样的效果,只需给它加上契约注解:

    @Contract("null -> true")
    fun String?.nullOrBlank(): Boolean {
        return this == null || this.isBlank()
    }
    

    添加注解后,编译器就能识别出函数返回false时接收者非空,此时访问input.length就不会报错了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:03:20