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

Kotlin中val与var声明计算属性的差异及相关编译疑问

Kotlin计算属性val与var的差异解析

关于val计算属性是否违背本意

首先明确:Kotlin里的val核心是只读,不是“值永远固定不变”。

你写的第一种方式:

val currentQuestionResId: Int
    get() = questionBank[qIdx].textResId

这是标准的只读计算属性,外部代码只能通过get()获取它的值,根本没法直接给它赋值。虽然每次调用get()返回的结果可能随qIdx或questionBank的变化而改变,但这完全符合val的设计初衷——禁止外部写入,只允许读取。所以完全没有违背val的本意。

为什么var计算属性要求初始化

这是因为var默认会隐式生成幕后字段(backing field),即使你写了自定义getter,编译器默认还是认为这个属性需要一个存储值的字段。而var是可写的,编译器要求必须初始化这个幕后字段,否则它不知道属性的初始状态是什么。

如果你想让var的计算属性不依赖幕后字段,必须同时自定义getter和setter,并且在setter里也不使用默认的field变量。比如:

var currentQuestionResId: Int
    get() = questionBank[qIdx].textResId
    set(value) {
        // 自行实现赋值逻辑,比如根据传入值修改qIdx
        qIdx = questionBank.indexOfFirst { it.textResId == value }
    }

这样编译器就不会要求初始化了,因为你已经完全接管了属性的读写逻辑,不需要默认的幕后字段。如果只写getter不写setter,编译器还是会认为需要幕后字段来存储值,所以必须初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:47:13