Kotlin: fun vs val



kotlin支持计算属性,但我不确定何时使用它们。

假设我有一个课:

class Car(val color: String)

并具有此功能,该功能如果汽车为白色,则返回true

fun isWhite(car: Car): Boolean {
  return car.color == "WHITE"
}

现在,我希望此函数为成员函数(a 方法);看起来像这样:

class Car(val color: String) {
  fun isWhite(): Boolean = color == "WHITE"
}

但也可以看起来像这样:

class Car(val color: String) {
  val isWhite: Boolean get() = color == "WHITE"
}

那么,哪个更好?

官方的kotlin编码约定在 functions vs属性中定义 以下内容:

在某些情况下,没有参数的功能可能与仅阅读属性互换。尽管语义是相似的,但何时偏爱一个风格的惯例。

在基础算法时更喜欢属性而不是函数:

  • 不扔
  • 计算(或在第一次运行时ca)很便宜
  • 如果对象状态没有更改,则返回相同的结果

因此,我将在上面的示例中使用val的CC_2,因为它没有投掷,因此计算字符串比较便宜,并且Carcolor无法更改,因为Car.color本身定义为val

编译差异

请注意,get()块的JVM字节码将与函数完全相同的代码编译为完全相同的代码。因此,两种方法在编译字节上都是相同的,并且没有性能差异。

要添加其他答案,这些是从书本 java到kotlin ,第11章 properties 的方法:

示例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())
}

个人喜好。

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

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