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,因为它不会抛出,所以字符串比较的计算成本很低,并且Carcolor 不能改变,因为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

kotlin:如何在两个片段之间传递数据

Android Kotlin Volley 如何从 JSONArray 中获取价值

五年 Java一朝转为 Kotlin,这份Kotlin协程入门指南太详细了

如何从 Firebase android kotlin 获取所有具有特定价值的孩子?

不要花大力气学 Kotlin