Kotlin中的可变Vals

本文探讨Kotlin中val和var的区别,指出val并非不可变而是只读。对于类属性,val和var指示是否有getter/setter。可定制的getter虽启用委派属性,但为使代码更易推理,建议不为类属性用自定义getter,只读属性值改变时用正常函数替换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

conver.jpg
当我第一次学习Kotlin时,觉得valvar之间的区别似乎很简单,val表示不可变,var表示可变。

真相比这更微妙,val不代表不可变,val意味着只读。这意味着你不允许明确写入val,但它不能保证它们是不可变的。[1]

原标题:Mutable vals in Kotlin

原文作者:Daniel Lew

原文地址:https://blog.danlew.net/2017/05/30/mutable-vals-in-kotlin/

可变类属性

对于变量,不可变和只读之间的区别是一个有争议的问题。没有办法编写val变量或覆盖它的检索方式,因此(对于所有意图和目的)它是不可变的。

但是,对于类属性,只读属性val会产生巨大的差异。

在属性的上下文中,valvar指示属性是否存在getter/setter。var既有getter又有setter,而val只有getter。

在简单的情况下,缺少setter意味着val类属性是不可变的。但是,可以为任何类属性添加自定义getter函数,允许您在每次有人访问该属性时返回您想要的任何内容。例如:

class Person(val birthDay: DateTime) {
  val age: Int
    get() = yearsBetween(birthDay, DateTime.now())
}

如您所见,没有明确的设置方法Person.age,但Person.age会在当前日期更改时更改值。

实际上,将其Person.age视为变量实际上是用词不当。它实际上是一个你正在调用的getter函数,它可能会改变调用值。

结论

当我在Kotlin学习可变vals时,我个人感到震惊。 我觉得被违背了valvar标记数据一样,不可变与可变是我学到的Kotlin的第一个很酷的功能之一!

据我所知,对于val类属性,可定制的getter有两个参数:

  1. 类属性只是getter / setter的简写,并且通常认为定制getter是正常的。
  2. 可自定义的getter启用委派属性。

委托属性是一个引人注目的用例,我将继续使用它们。但是,我发现在val暗示不可变引用时,更容易推理代码。不可变性使代码(尤其是并发代码)更容易使用。

因此,我选择不为val类属性使用自定义getter 。如果只读类属性随时间改变值,我改为用正常函数替换该属性:

class Person(val birthDay: DateTime) {
  fun age(): Int = yearsBetween(birthDay, DateTime.now())
}

这种偏好是Kotlin编码惯例所建议的。 它声明只有在基础算法时才应该优先考虑函数的属性:

  • 不用throw
  • 有复杂性
  • 计算起来很低廉(或在第一次运行时计算)
  • 通过调用返回相同的结果

覆盖getter并更改参考值会违反最后一个条件,因此请避免这样做!


[1]: 为了简洁起见,在这篇文章中,“不可变”实际上意味着“不可变参考”。 您始终可以引用可变对象(如ArrayList)。 在这种情况下防止可变性需要比简单使用val更先进的技术,我不会在这里讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值