Kotlin 值关键字
最后修改于 2025 年 4 月 19 日
Kotlin 的 `value` 关键字(与 `val` 一起使用)声明不可变变量,这些变量不能被重新赋值。 不可变变量是 Kotlin 采用更安全、更可预测的代码的关键特性。 本教程深入探讨了 `val` 关键字,并提供了实用示例。
基本定义
Kotlin 中的 `val` 关键字声明只读(不可变)变量。 一旦赋值,`val` 就不能被重新赋值。 这与声明可变变量的 `var` 不同。 不可变变量有助于防止意外修改。
基本 val 声明
`val` 最简单的用法是声明一个具有固定值的不可变变量。 该值可以被赋值一次,之后不能被更改。
package com.zetcode
fun main() {
val message = "Hello, Kotlin"
// message = "Changed" // Compilation error
println(message) // Output: Hello, Kotlin
}
在这里,我们声明一个名为 `message` 的 `val` 并为其分配一个字符串值。 尝试重新分配它将导致编译错误。 该值在其作用域内保持不变。
带有显式类型的 val
您可以在声明 `val` 时显式指定其类型。 当您想要清楚地说明变量的类型或无法推断类型时,这很有用。
package com.zetcode
fun main() {
val count: Int = 42
val pi: Double = 3.14159
println(count) // Output: 42
println(pi) // Output: 3.14159
}
`count` 和 `pi` 都使用显式类型声明。 初始化后,这些值不能被更改。 显式类型有助于使代码更具可读性和可维护性。
带有计算值的 val
`val` 可以使用计算值进行初始化。 计算只发生一次,在初始化时,结果变为不可变。
package com.zetcode
fun main() {
val radius = 5.0
val area = Math.PI * radius * radius
println("Area: $area") // Output: Area: 78.53981633974483
}
`area` val 由 `radius` 和 `Math.PI` 计算得到。 计算后,面积不能被更改。 这种模式对于不应在计算后更改的派生值很常见。
类属性中的 val
类属性可以声明为 `val` 以使其不可变。 这些属性必须在声明或构造函数中初始化。
package com.zetcode
class Person(val name: String, val age: Int)
fun main() {
val person = Person("Alice", 30)
// person.name = "Bob" // Compilation error
println("${person.name} is ${person.age}") // Output: Alice is 30
}
`Person` 类有两个不可变属性。 创建 `Person` 后,其姓名和年龄不能更改。 这确保了对象的状态保持一致。
带有自定义 getter 的 val
`val` 可以有一个自定义 getter,它会在每次访问时计算其值。 尽管是一个 `val`,但返回的值可能会根据其他状态而变化。
package com.zetcode
class Circle(val radius: Double) {
val area: Double
get() = Math.PI * radius * radius
}
fun main() {
val circle = Circle(5.0)
println(circle.area) // Output: 78.53981633974483
// circle.area = 100.0 // Compilation error
}
`area` 属性会在每次访问时计算,但不能直接设置。 如果 `radius` 发生变化,该值会发生变化,但该属性仍为只读。
函数参数中的 val
Kotlin 中的函数参数始终是不可变的,类似于使用 `val` 声明。 您不能在函数体中重新分配它们。
package com.zetcode
fun greet(name: String) {
// name = "Bob" // Compilation error
println("Hello, $name!")
}
fun main() {
greet("Alice") // Output: Hello, Alice!
}
`greet` 函数中的 `name` 参数是不可变的。 这可以防止参数的意外重新分配,这可能会导致复杂函数中的错误。
带有惰性初始化的 val
可以使用 `by lazy` 委托与 `val` 一起实现惰性初始化。 该值仅在首次访问时计算,然后被缓存。
package com.zetcode
fun main() {
val lazyValue: String by lazy {
println("Computed!")
"Hello"
}
println(lazyValue) // Output: Computed! then Hello
println(lazyValue) // Output: Hello (no recomputation)
}
`lazyValue` 仅在首次访问时计算。 后续访问将返回缓存值。 这对于可能不需要的昂贵操作很有用。
val 的最佳实践
- 首选 val 而不是 var: 默认使用不可变变量,使代码更具可预测性。
- 用于常量: 不应更改的值应使用 `val` 声明。
- 考虑惰性初始化: 对于昂贵的计算,使用 `by lazy` 和 `val`。
- 在类属性中使用: 使属性不可变,除非它们需要更改。
- 与自定义 getter 结合使用: 对于应该只读的派生值。
来源
本教程深入探讨了 Kotlin 的 `val` 关键字,展示了声明和使用不可变变量的各种方法。 我们探讨了基本声明、类属性、自定义 getter 和惰性初始化。 正确使用不可变性可以使您的代码更安全,更容易推理。
作者
列出 所有 Kotlin 教程。