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

Kotlin中val属性为何可变更?自定义RecyclerView适配器疑问

为什么Kotlin的val属性mySelectedIndex没有报错?

先帮你理清楚核心问题:你混淆了Kotlin中val属性的不可变性范围,咱们一步步拆解:

首先回顾你的场景:

Code B是带有单选按钮的自定义RecyclerView适配器。在Code A的fun methodA()和fun methodB()中均修改了mCustomAdapter,因此get() = mCustomAdapter.getSelectedIndex()的引用也发生变化,这意味着val属性mySelectedIndex从不同地址获取值。我认为val属性不可被修改,为何应用未出现报错?

Code A代码片段:

private lateinit var mCustomAdapter: CustomAdapter 
private val mySelectedIndex get () = mCustomAdapter.getSelectedIndex()

1. val限制的是“属性本身不能被赋值”,不是“返回值不能变”

Kotlin里的val关键字,本质是禁止对属性本身进行重新赋值,而不是要求它返回的值必须固定不变。

  • 对于普通的val属性(比如val name = "Alice"),它背后有一个隐藏的存储字段,getter默认返回这个固定值,而且你不能写name = "Bob"这种赋值操作。
  • 但你的mySelectedIndex是一个计算属性(computed property)——它没有自己的存储字段,每次你访问它的时候,都会执行get()里的代码,去调用mCustomAdapter.getSelectedIndex()获取最新值。val在这里只限制了你不能做mySelectedIndex = 10这种直接赋值的操作,完全允许getter动态返回不同结果。

2. 修改mCustomAdapter的引用,完全符合val的规则

你在methodA()和methodB()里修改的是mCustomAdapter这个var变量的引用(比如把它换成一个新的CustomAdapter实例),但mySelectedIndex的getter只是每次去拿当前mCustomAdapter实例的选中索引而已。

你从来没有给mySelectedIndex本身赋值,只是每次访问它时,它去动态获取最新的结果——这完全在val的规则允许范围内,所以不会报错。

3. 举个简单的类比例子

看这段代码,完全合法且符合预期:

var count = 0
val currentCount get() = count

fun main() {
    println(currentCount) // 输出0
    count++
    println(currentCount) // 输出1
}

这里currentCount是val,但它的返回值会随着count的变化而变化——因为每次访问都会执行getter逻辑,而val只禁止你给currentCount直接赋值,比如currentCount = 5这种操作才会报错。

总结

你的mySelectedIndex作为计算属性,val的作用只是阻止你直接给它赋值,而它的getter可以自由地动态返回不同的结果,这完全符合Kotlin的语法规则,所以应用不会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:18:52