Kotlin 变量与函数

Kotlin 变量与函数

Kotlin 是一门静态类型语言,运行在 Java 虚拟机之上。它的变量和函数设计既保持了与 Java 的兼容,又引入了许多更简洁的写法。下面从最基础的概念开始介绍。

变量声明

Kotlin 声明变量使用两个关键字:valvar

  • val 表示不可变的引用。一旦赋值,就不能再指向另一个对象。这类似 Java 里的 final 变量。
  • var 表示可变的引用。可以随时改变它指向的对象。
kotlin 复制代码
val name: String = "Alice"   // 只读
var age: Int = 25            // 可读写
age = 26                     // 允许
// name = "Bob"              // 这行会报编译错误

要注意的是,val 只保证引用不变,并不保证对象内部状态不变。比如:

kotlin 复制代码
val list = mutableListOf(1, 2, 3)
list.add(4)                  // 允许,list 这个引用没变
// list = mutableListOf(5)   // 不允许,因为 list 是 val

通常,如果一个变量在初始化后不再改变,就使用 val,这样能让代码更易理解。

类型推导

Kotlin 可以根据初始化表达式的值自动推断出变量的类型,所以大部分时候可以不写类型声明。

kotlin 复制代码
val message = "Hello"        // 编译器推断为 String
var count = 100              // 推断为 Int

但有些场合需要显式写出类型:

  • 变量没有立刻初始化(比如先声明,后面再赋值)。
  • 希望变量使用接口类型而不是具体实现类,例如声明为 List<String> 而实际赋值 ArrayList
  • 避免数字类型被错误推断,例如 val number = 100L 明确指定长整型,或者写成 val number: Long = 100

对于需要延迟初始化的可变变量,可以使用 lateinit。这只能用于 var,且不能是基本类型(如 Int、Double 等)。

kotlin 复制代码
lateinit var description: String
// 后面的代码中再赋值
description = "Delayed"

属性与访问器

在类里面声明的变量称为属性(property)。每个属性都会自动生成默认的 getter(对于 val)和 setter(对于 var)。你也可以自己编写访问器。

kotlin 复制代码
class Circle(val radius: Double) {
    val area: Double
        get() = Math.PI * radius * radius   // 每次访问时计算
}

对于 var 属性,可以自定义 setter,例如添加校验逻辑:

kotlin 复制代码
var temperature: Int = 0
    set(value) {
        if (value >= -273) {
            field = value   // field 代表背后的存储字段
        }
    }

函数定义

函数使用 fun 关键字,返回类型写在参数列表后面。

kotlin 复制代码
fun add(a: Int, b: Int): Int {
    return a + b
}

如果函数体只有一个表达式,可以简化为表达式体,省略花括号和 return

kotlin 复制代码
fun add(a: Int, b: Int) = a + b   // 返回类型自动推断为 Int

默认参数与命名参数

Kotlin 允许给函数参数设定默认值,这样调用时可以不传该参数。

kotlin 复制代码
fun greet(name: String, prefix: String = "Hello") {
    println("$prefix, $name")
}
// 调用
greet("Tom")                     // 输出 Hello, Tom
greet("Tom", "Hi")               // 输出 Hi, Tom

命名参数允许在调用时指定参数名称,这样参数顺序可以任意调整,也提高了可读性。

kotlin 复制代码
greet(prefix = "Good morning", name = "Tom")

可变参数

使用 vararg 关键字可以让函数接受任意数量的同类型参数。

kotlin 复制代码
fun sum(vararg numbers: Int): Int {
    return numbers.sum()
}
sum(1, 2, 3, 4)   // 返回 10

局部函数

在函数内部还可以定义另一个函数,这称为局部函数。它通常用来封装仅在当前函数内需要重复使用的逻辑。

kotlin 复制代码
fun process(input: String) {
    fun validate(s: String): Boolean {
        return s.isNotBlank()
    }
    if (validate(input)) {
        // 处理 input
    }
}

局部函数可以访问外层函数的参数和局部变量。

函数类型与高阶函数

Kotlin 中函数也是一种类型,可以将函数作为参数传递给另一个函数,或者作为返回值。函数类型的写法是 (参数类型) -> 返回类型

kotlin 复制代码
fun operate(x: Int, y: Int, op: (Int, Int) -> Int): Int {
    return op(x, y)
}
val result = operate(10, 5) { a, b -> a - b }   // 结果为 5

这样的特性让集合操作(如 mapfilter)变得很方便。

作用域与可见性

变量和函数的作用域由声明的位置决定:

  • 在文件顶层声明的,属于全局范围,但可以用 private 限制仅当前文件可见。
  • 在类内部声明的,属于该类的成员。
  • 在函数内部声明的,只在该函数内有效。

可见性修饰符有 privateprotectedinternalpublic,默认是 public

空安全

Kotlin 的类型系统区分可空类型和不可空类型。在类型后面加 ? 表示可以为 null

kotlin 复制代码
var nullable: String? = null
var nonNull: String = "value"
// nonNull = null   // 编译错误,不允许

函数参数和返回值也遵循这个规则。当访问可空对象的成员时,需要使用安全调用 ?. 或者非空断言 !!!! 要谨慎使用,它会在值为 null 时抛出异常)。

kotlin 复制代码
fun getLength(s: String?): Int {
    return s?.length ?: 0   // 如果 s 为 null,返回 0
}

这样可以在编译期避免大量的空指针异常。

相关推荐
breeze jiang2 小时前
JavaScript 单例模式:用静态属性保证 Popup 只创建一次
开发语言·javascript·单例模式
snow@li3 小时前
SpringBoot:AOP日志切面全景梳理/原理+流程+实战+避坑
java·开发语言·spring boot
Nil2083 小时前
C++ emplace_back 与 push_back 详解
开发语言·c++
我命由我123453 小时前
Android Drawable - gradient
android·java·java-ee·kotlin·android studio·android-studio·android runtime
clear sky .3 小时前
[freertos源码阅读]task.c任务篇
c语言·开发语言
Kapaseker4 小时前
AI 时代,读源码还有用吗?从 Kotlin 集合排序说起
android·kotlin
XR1234567884 小时前
工业园区整体组网,方案对比怎么选?
开发语言·php
东东最爱敲键盘4 小时前
day9.C++多态之虚函数
开发语言·c++
码云数智-园园4 小时前
类似小鹅通的知识付费小程序平台有哪些
开发语言
snow@li4 小时前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm