为什么要将val或var放在kotlin类构造函数中

Exo*_*Kid 5 in-class-initialization kotlin

刚刚学习Kotlin在下面的第一个代码val中,其他代码中没有关键字,没有,如果valvar被省略,这里有什么不同?

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

class Person(firstName: String, lastName: String) {
}
Run Code Online (Sandbox Code Playgroud)

zap*_*apl 10

如果省略valvar在构造函数中,那么唯一可以访问这些参数的地方是在构造时评估的初始化语句.请参阅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)
}
Run Code Online (Sandbox Code Playgroud)

但它也适用于授权使用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))
}
Run Code Online (Sandbox Code Playgroud)

或者在财产代表团

class Person4(firstName: String, lastName: String) {
    val fullName: String by lazy { "$firstName $lastName" }
}
Run Code Online (Sandbox Code Playgroud)

注意:在初始化时捕获闭包,因此lazy最终计算时值仍然可用.


Mik*_*ike 9

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