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 教程。