Kotlin 变量与函数

Kotlin 变量与函数

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

变量声明

Kotlin 声明变量使用两个关键字:val 和 var。

  • 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

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

作用域与可见性

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

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

可见性修饰符有 private、protected、internal、public,默认是 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
}

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

相关推荐
MayZork7 分钟前
Qt 文件操作:QSaveFile 与 QTemporaryFile(含 QTemporaryDir)实战
开发语言·qt
北冥you鱼19 分钟前
Go 语言空接口(interface{})使用场景与最佳实践
开发语言·windows·golang
xh didida29 分钟前
Linux -- 基础IO
linux·服务器·开发语言·c++
个 人 练 习 生1 小时前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
2601_966949651 小时前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
坤坤子吖1 小时前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
奋斗的阿狸_19861 小时前
ESP32-S3 + ES7210 四通道麦克风录音上传方案
c语言·开发语言·fpga开发
weixin199701080161 小时前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存
ACP广源盛139246256732 小时前
Type‑C 扩展坞方案选型笔记|国产 DP1.4 转 HDMI2.0 桥接芯片 GSV2201S @ACP评估
c语言·开发语言·笔记·硬件架构·硬件工程·国产芯片
niucloud-admin2 小时前
JAVA V6 多商户商城 开发文档——JAVA服务端
java·开发语言