ZetCode

Kotlin var 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 提供了两个关键字用于变量声明:valvarvar 关键字声明可变变量,这些变量可以被重新赋值。本教程将通过实际例子深入探讨 var 关键字。

基本定义

Kotlin 中的 var 关键字声明一个可变变量。与 val 不同,使用 var 声明的变量可以在初始化后重新赋值。Kotlin 支持 var 声明的类型推断。

基本 var 声明

var 声明的最简单形式包括关键字、变量名、可选类型和初始值。类型可以从初始化器推断出来。

BasicVar.kt
package com.zetcode

fun main() {

    var count = 10
    println(count) // Output: 10
    
    count = 20
    println(count) // Output: 20
}

这里,我们声明一个可变变量 count,并将其初始化为 10。Kotlin 将类型推断为 Int。然后,我们将其重新赋值为 20,这展示了可变性。类型在声明后保持不变。

显式类型声明

虽然 Kotlin 可以推断类型,但您可以显式声明变量类型。当您想明确指定类型或稍后初始化时,这很有用。

ExplicitType.kt
package com.zetcode

fun main() {

    var message: String
    message = "Hello, Kotlin"
    
    println(message) // Output: Hello, Kotlin
    
    message = "New message"
    println(message) // Output: New message
}

我们声明 message 并显式指定 String 类型,稍后进行初始化。只要新值是 String,就可以重新赋值该变量。这展示了声明和初始化的分离。

使用 lateinit 进行延迟初始化

对于无法在构造函数中初始化的非空属性,Kotlin 提供了 lateinit。此修饰符允许延迟初始化 var 属性。

LateInit.kt
package com.zetcode

class User {
    lateinit var name: String
    
    fun initializeName() {
        name = "John Doe"
    }
}

fun main() {

    val user = User()
    user.initializeName()
    
    println(user.name) // Output: John Doe
}

name 属性使用 lateinit 声明并在稍后初始化。在初始化之前尝试访问它将抛出异常。这对于依赖注入场景很有用。

变量作用域

使用 var 声明的变量遵循标准的范围规则。它们在其声明块内可见,并且可以隐藏外部范围内的变量。

VariableScope.kt
package com.zetcode

fun main() {

    var x = 10
    println("Outer x: $x") // Output: Outer x: 10
    
    if (true) {
        var x = 20
        println("Inner x: $x") // Output: Inner x: 20
    }
    
    println("Outer x: $x") // Output: Outer x: 10
}

此示例演示了变量隐藏。内部 x 在 if 块内隐藏了外部的 x。对内部变量的更改不会影响外部变量。每个变量存在于其自己的作用域中。

类型更改限制

虽然 var 允许重新赋值,但变量的类型在声明时就已固定。您不能在声明后分配不同类型的值。

TypeRestriction.kt
package com.zetcode

fun main() {

    var value: Number = 10
    println(value) // Output: 10
    
    value = 20.5
    println(value) // Output: 20.5
    
    // value = "Hello" // Compile error
}

value 变量声明为 Number,因此它可以保存任何数值类型。但是,分配一个 String 将导致编译错误。类型系统即使使用可变变量也能确保类型安全。

类中的属性

在类中,var 声明可变属性。这些属性可以具有自定义的 getter 和 setter,同时保持属性的可变性。

ClassProperties.kt
package com.zetcode

class Person {
    var name: String = ""
        set(value) {
            field = value.trim()
        }
    
    var age: Int = 0
        set(value) {
            field = if (value >= 0) value else 0
        }
}

fun main() {

    val person = Person()
    person.name = "  John  "
    person.age = -5
    
    println(person.name) // Output: John
    println(person.age) // Output: 0
}

Person 类有两个具有自定义 setter 的可变属性。名称 setter 移除空格,而年龄 setter 确保非负值。这展示了 var 属性如何封装逻辑。

顶级变量

var 可用于声明可变的顶级变量。这些变量在整个文件中都可访问,并且可以导入到其他文件中。

TopLevelVar.kt
package com.zetcode

var counter = 0

fun incrementCounter() {
    counter++
}

fun main() {

    println(counter) // Output: 0
    incrementCounter()
    println(counter) // Output: 1
}

counter 变量在顶层声明,并且可以被文件中的任何函数修改。这展示了全局可变状态,应谨慎使用,以避免可维护性问题。

使用 var 的最佳实践

来源

Kotlin 变量文档

本教程深入探讨了 Kotlin 的 var 关键字,展示了如何声明和使用可变变量。我们探讨了各种场景,包括属性、作用域和类型安全。正确使用可变变量有助于平衡 Kotlin 代码中的灵活性和可维护性。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经写了 1400 多篇文章和 8 本电子书。我有超过八年的编程教学经验。

列出 所有 Kotlin 教程