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

如何定义Kotlin扩展函数限制可空与非空类型的调用?

Kotlin 限制扩展函数仅适用于可空/非空类型

问题场景

希望实现两个扩展函数,使得以下代码中标记的两处调用无法通过编译:

fun f(nullString: String?, nonNullString: String) {
    nullString.ext() // 预期错误:非空扩展不能直接用在可空接收者上
    nullString.nullExt() // 正常:可空扩展匹配可空接收者
    nonNullString.ext() // 正常:非空扩展匹配非空接收者
    nonNullString.nullExt() // 预期错误:可空扩展不能用在非空接收者上
}

当前写法仅能实现第一处报错,最后一处因String是String?的子类型仍可编译:

fun String.ext(): Unit = TODO()
fun String?.nullExt(): Unit = TODO()

解决方案

通过泛型约束结合Nothing?,可以让nullExt仅对String?类型生效,同时拒绝非空String:

fun String.ext(): Unit = TODO()

// 泛型约束限定T必须是String?,且同时是Nothing?的子类型
fun <T : String?> T.nullExt(): Unit where T : Nothing? = TODO()

原理说明

  • Nothing?是Kotlin中所有可空类型的父类型,但只有null是它的唯一实例。
  • 当接收者为String?时,编译器可以推导出T为String?,满足T : String?和T : Nothing?的双重约束,因此可以正常调用。
  • 当接收者为非空String时,String并非Nothing?的子类型,无法满足约束条件,编译器会报错找不到匹配的扩展函数。

验证效果

使用上述定义后:

  • nullString.ext():因String?无法直接调用String的非空扩展,必须使用安全调用?.或非空断言!!.,编译报错。
  • nonNullString.nullExt():非空String不满足泛型约束,编译报错。
  • 其余两处调用均正常通过编译,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:05:21