Kotlin:乐趣与价值
Posted
技术标签:
【中文标题】Kotlin:乐趣与价值【英文标题】:Kotlin: fun vs val 【发布时间】:2019-07-23 18:10:40 【问题描述】:Kotlin 支持计算属性,但我不确定何时使用它们。
假设我有一堂课:
class Car(val color: String)
如果汽车是白色的,这个函数会返回true
:
fun isWhite(car: Car): Boolean
return car.color == "WHITE"
现在我希望这个函数成为一个成员函数(一个方法);这看起来像这样:
class Car(val color: String)
fun isWhite(): Boolean = color == "WHITE"
但它也可以是这样的:
class Car(val color: String)
val isWhite: Boolean get() = color == "WHITE"
那么,哪个更好?
【问题讨论】:
查看相关Swift question。 另见this medium article。 【参考方案1】:个人喜好。
我的观点是,如果您不需要传递任何东西,那么将其创建为属性。
但如果你需要传递更多信息,它必须是一个函数!
【讨论】:
【参考方案2】:官方Kotlin Coding Conventions 在Functions vs Properties部分定义如下:
在某些情况下,没有参数的函数可以与只读属性互换。尽管语义相似,但在何时偏好一种而不是另一种方面存在一些风格约定。
当底层算法优先使用属性而不是函数:
不扔 计算成本低(或在第一次运行时缓存) 如果对象状态未更改,则在调用中返回相同的结果
所以,我将在上面的示例中使用val
来表示isWhite
,因为它不会抛出,所以字符串比较的计算成本很低,并且Car
的color
不能改变,因为Car.color
本身定义为 val
。
编译差异
请注意,get()
块的 JVM 字节码将被编译为与函数完全相同的代码。因此,对于编译后的字节码和there is no performance difference,这两种方法都是相同的。
【讨论】:
有人能解释一下“不抛出”是什么意思吗,是“我确定这个属性永远不会抛出任何异常”吗? @elliotching 是的,没错。 关于“计算成本低” - 这不是实现细节吗?【参考方案3】:添加其他答案,这些来自Java to Kotlin一书,第 11 章属性的方法:
示例 1
假设我们想将 age 添加到这个类中:
data class Person(val dateOfBirth: LocalDate)
我们可以通过dateOfBirth
属性轻松计算年龄(忽略时区)。但这不仅仅取决于该属性。这也取决于我们何时调用它。
虽然不太可能,fred.age == fred.age
可以返回 false
。
年龄是一个动作;它的结果取决于它何时被调用。特性
应该是计算,是永恒的并且只依赖于他们的输入,在这种情况下是dateOfBirth
属性。
因此,age()
应该是一个函数,而不是一个属性:
data class Person(val dateOfBirth: LocalDate)
fun age() = Period.between(dateOfBirth, LocalDate.now()).years
示例 2
如果我们想要对象的所有其他属性的加密哈希怎么办?
这是一个计算(对于不可变对象),但如果计算成本很高,它应该是方法hash()
而不是属性hash
。我们甚至可能想在其名称中暗示该方法的成本:
data class PersonWithProperties(
val givenName: String,
val familyName: String,
val dateOfBirth: LocalDate
)
fun computeHash(): ByteArray =
someSlowHashOf(givenName, familyName, dateOfBirth.toString())
【讨论】:
以上是关于Kotlin:乐趣与价值的主要内容,如果未能解决你的问题,请参考以下文章
未能将价值纳入日志消息? Kotlin - Firebase
Android Kotlin Volley 如何从 JSONArray 中获取价值
五年 Java一朝转为 Kotlin,这份Kotlin协程入门指南太详细了