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

Kotlin智能转换因接口属性被禁用,除!!外还有其他解决办法吗?

解决方案:Smart cast disabled 错误处理(非!!断言方式)

错误原因

Kotlin无法对接口的open属性做智能转换——接口属性默认是open的,子类可重写其getter方法,Kotlin无法保证你在检查request.title == null后,再次调用request.title时它不会变为null。

方案1:将属性赋值给局部变量

把接口属性赋值给局部val变量,局部变量不可变,Kotlin可以安全完成智能转换:

override fun validate(request: SendMessageRequestBase?): ValidationResult {
    val errors = ValidationResult()
    request ?: run {
        errors.addError(ValidationError.create("Request body is required"))
        return errors
    }

    val title = request.title
    if (title == null) {
        errors.addError(ValidationError.create("title (including NL title) is required"))
    } else if (title.nl.isNullOrEmpty()) {
        errors.addError(ValidationError.create("NL title is required"))
    }

    val body = request.body
    if (body == null) {
        errors.addError(ValidationError.create("body (including NL body) is required"))
    } else if (body.nl.isNullOrEmpty()) {
        errors.addError(ValidationError.create("NL body is required"))
    }

    return errors
}

方案2:使用let/run作用域函数

利用作用域函数在非空分支内安全访问属性,避免重复调用接口属性:

override fun validate(request: SendMessageRequestBase?): ValidationResult {
    val errors = ValidationResult()
    request ?: run {
        errors.addError(ValidationError.create("Request body is required"))
        return errors
    }

    // 处理title逻辑
    request.title?.run {
        if (nl.isNullOrEmpty()) {
            errors.addError(ValidationError.create("NL title is required"))
        }
    } ?: run {
        errors.addError(ValidationError.create("title (including NL title) is required"))
    }

    // 处理body逻辑
    request.body?.run {
        if (nl.isNullOrEmpty()) {
            errors.addError(ValidationError.create("NL body is required"))
        }
    } ?: run {
        errors.addError(ValidationError.create("body (including NL body) is required"))
    }

    return errors
}

方案3:修改接口为抽象类并限制属性重写

如果确定所有实现类的属性都是不可变的(比如你的数据类),可以将接口改为抽象类,把属性标记为final,让Kotlin能安全进行智能转换:

abstract class SendMessageRequestBase(
    final override val title: TextLocalization?,
    final override val body: TextLocalization?,
    final override val data: Map<String, String>?
) {
    val title: TextLocalization?
    val body: TextLocalization?
    val data: Map<String, String>?
}

// 数据类实现抽象类
data class SendMessageRequest(
    val pushId: String,
    override val title: TextLocalization?,
    override val body: TextLocalization?,
    override val data: Map<String, String>?
) : SendMessageRequestBase(title, body, data)

注:此方案会降低代码灵活性(接口改为抽象类),仅在无需多实现场景下使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:20:28