【问题标题】:Kotlin: fun vs valKotlin:乐趣与价值
【发布时间】: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"
}

那么,哪个更好?

【问题讨论】:

标签: kotlin methods properties computed-properties


【解决方案1】:

个人喜好。

我的观点是,如果您不需要传递任何东西,那么将其创建为属性。

但如果你需要传递更多信息,它必须是一个函数!

【讨论】:

    【解决方案2】:

    官方Kotlin Coding ConventionsFunctions 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())
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 2016-11-05
      • 2010-12-24
      相关资源
      最近更新 更多