26

刚学 Kotlin 在下面的第一个代码中有val关键字 right 在其他代码中没有,如果省略valand有什么不同?var

class Person(val firstName: String, val lastName: String) {
}

class Person(firstName: String, lastName: String) {
}
4

2 回答 2

45

如果省略 val 或 var 则它们将不是属性,而是传递给构造函数的参数。您将无法在构造函数之外使用它们。

于 2018-09-29T09:46:42.457 回答
25

如果在构造函数中省略valvarin,则唯一可以访问这些参数的位置是在构造时评估的初始化语句。请参阅https://kotlinlang.org/docs/reference/classes.html

当您想在存储值之前对其进行处理时,这很有用。在 Java 中,您可以将该代码作为构造函数体

class Person(firstName: String, lastName: String) {
    // directly in val / var declarations
    val firstName = firstName.capitalize()
    val lastName = lastName

    // in init blocks
    val fullName: String
    init {
        fullName = "$firstName $lastName"
    }

    // secondary constructors can only see their own parameters
    // and nothing else can access those
    constructor(fullName: String) : this("", fullName)
}

但它也适用于委托使用by

interface Named {
    fun getName(): String
}
class Human(private val fname: String, private val lname: String) : Named {
    override fun getName() = "$fname + $lname" // functions need val since
                                               // value is resolved after construction
}
class Person2(firstName: String, lastName: String) : Named by Human(firstName, lastName)

class Person3(human: Human) : Named by human {
    constructor(firstName: String, lastName: String): this(Human(firstName, lastName))
}

或在财产委托中

class Person4(firstName: String, lastName: String) {
    val fullName: String by lazy { "$firstName $lastName" }
}

lazy注意:闭包是在初始化时捕获的,因此在最终评估时这些值仍然可用。

于 2018-09-29T10:34:30.217 回答