kotlin中关于 val 的理解补充
在刚开始学 Kotlin 时,我觉得 val 和 var 之间的区别很简单:val 表示不可变的,var 表示可变的。
但实际上 val 表示的是只读( read-only ),也就是你不能将值再写入 val,但并不意味着其是不可变的。
对于普通变量来说,不可变( immutable )和只读( read-only )之间没什么区别。因为你没有办法复写一个 val 变量,所以在这时确实是不可变的。
但如果是对于类的成员变量来说,那只读和不可变的区别可就大了。
在 Kotlin 的类中,val 和 var 是用于表示属性是否有 getter/setter:
- var:同时有 getter 和 setter。
- val:只有 getter。
这里是可以通过自定义 getter 函数来返回不同的值:
class Person(val birthDay: DateTime) {
val age: Int
get() = yearsBetween(birthDay, DateTime.now())
}
可以看到,虽然没有方法来设置 age 的值,但会随着当前日期的变化而变化。
这种情况下,我建议不要自定义 val 属性的 getter 方法。如果一个只读的类属性会随着某些条件而变化,那么应当用函数来替代:
class Person(val birthDay: DateTime) {
fun age(): Int = yearsBetween(birthDay, DateTime.now())
}
这也是 Kotlin 代码约定中所提到的,当具有下面列举的特点时使用属性,不然更推荐使用函数:
- 不会抛出异常。
- 具有 O(1) 的复杂度。
- 计算时的消耗很少。
- 同时多次调用有相同的返回值。
因此上面提到的,自定义 getter 方法并随着当前时间的不同而返回不同的值违反了最后一条原则。大家也要尽量的避免这种情况。: )