Kotlin 语言基础

知识结构

什么是 Kotlin

Kotlin 是 JetBrains 开发的现代编程语言,2017 年被 Google 宣布为 Android 官方开发语言。

核心特点:

  • 简洁:比 Java 代码量少很多
  • 安全:内置空安全机制,减少 NullPointerException
  • 互操作:与 Java 100% 兼容,可以混合使用
  • 多平台:支持 JVM、Android、JS、Native

Hello World

fun main() {
println("Hello, Kotlin!")
}

变量与常量

变量声明

// var: 可变变量
var name = "Kotlin"
name = "Android" // OK - 可以重新赋值
// val: 不可变变量(类似 Java 的 final)
val version = 1.9
// version = 2.0 // Error - 不能重新赋值
// 显式类型声明
var age: Int = 25
val pi: Double = 3.14159
val isActive: Boolean = true

val 与 var 对比

特性valvar
可重新赋值不可以可以
类似 Javafinal 变量普通变量
推荐程度优先使用需要修改时使用
// 推荐:优先使用 val
val name = "Kotlin" // 不会被修改
val list = mutableListOf(1, 2, 3) // 引用不变,内容可变
// 只有需要重新赋值时才用 var
var counter = 0
counter++

编译时常量

// const val: 编译时常量,只能用于顶层或 object 中
const val MAX_COUNT = 100
const val APP_NAME = "MyApp"
object Config {
const val VERSION = "1.0.0"
}

基本数据类型

数字类型

// 整数
val byte: Byte = 127 // 8位
val short: Short = 32767 // 16位
val int: Int = 2147483647 // 32位
val long: Long = 9223372036854775807L // 64位
// 浮点数
val float: Float = 3.14f // 32位
val double: Double = 3.14159 // 64位
// 数字字面量
val million = 1_000_000 // 下划线分隔,更易读
val hex = 0xFF // 十六进制
val binary = 0b1010 // 二进制

布尔与字符

val isTrue: Boolean = true
val isFalse: Boolean = false
val char: Char = 'A'
val unicode: Char = '\u0041' // 也是 'A'

字符串

// 普通字符串
val str = "Hello, Kotlin"
// 字符串模板
val name = "World"
println("Hello, $name!") // Hello, World!
println("Length: ${name.length}") // Length: 5
// 多行字符串
val multiLine = """
Line 1
Line 2
Line 3
""".trimIndent()
// 常用操作
"hello".uppercase() // HELLO
" trim ".trim() // trim
"hello".contains("ell") // true
"hello".replace("l", "L") // heLLo
"a,b,c".split(",") // [a, b, c]
"hello".substring(0, 3) // hel

空安全

Kotlin 的类型系统区分可空类型和非空类型,从根本上避免空指针异常。

可空类型

// 非空类型:不能赋值为 null
var name: String = "Kotlin"
// name = null // Error - 编译错误
// 可空类型:使用 ? 标记
var nullableName: String? = "Kotlin"
nullableName = null // OK

安全调用

val name: String? = null
// 安全调用操作符 ?.
println(name?.length) // null(不会崩溃)
// 链式安全调用
val city = user?.address?.city
// Elvis 操作符 ?:(空值合并)
val length = name?.length ?: 0
val displayName = name ?: "Unknown"
// 非空断言 !!(谨慎使用)
val len = name!!.length // 如果 name 为 null,抛出异常

let 作用域函数

val name: String? = "Kotlin"
// 仅当非空时执行
name?.let {
println("Name is $it")
println("Length is ${it.length}")
}
// 等价于
if (name != null) {
println("Name is $name")
}

函数

基本函数

// 普通函数
fun add(a: Int, b: Int): Int {
return a + b
}
// 单表达式函数
fun multiply(a: Int, b: Int): Int = a * b
// 返回类型推断
fun subtract(a: Int, b: Int) = a - b
// 无返回值(Unit 可省略)
fun greet(name: String) {
println("Hello, $name!")
}

默认参数与命名参数

// 默认参数
fun greet(name: String, greeting: String = "Hello") {
println("$greeting, $name!")
}
greet("Alice") // Hello, Alice!
greet("Bob", "Hi") // Hi, Bob!
// 命名参数
fun createUser(name: String, age: Int, email: String) {
println("$name, $age, $email")
}
createUser(
name = "Alice",
email = "alice@example.com",
age = 25 // 顺序可以不同
)

扩展函数

// 为 String 添加扩展函数
fun String.addExclamation(): String {
return this + "!"
}
println("Hello".addExclamation()) // Hello!
// 为 Int 添加扩展函数
fun Int.isEven(): Boolean = this % 2 == 0
println(4.isEven()) // true
println(5.isEven()) // false

Lambda 表达式

// Lambda 基本语法
val sum = { a: Int, b: Int -> a + b }
println(sum(3, 4)) // 7
// 类型声明在变量上
val multiply: (Int, Int) -> Int = { a, b -> a * b }
// 单参数可用 it
val double: (Int) -> Int = { it * 2 }
println(double(5)) // 10
// 作为函数参数
fun operate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}
println(operate(10, 5, { x, y -> x + y })) // 15
println(operate(10, 5) { x, y -> x - y }) // 5 - 尾随 lambda

高阶函数

// 函数作为参数
fun repeat(times: Int, action: (Int) -> Unit) {
for (i in 0 until times) {
action(i)
}
}
repeat(3) { index ->
println("Index: $index")
}
// 函数作为返回值
fun multiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
val triple = multiplier(3)
println(triple(5)) // 15

控制流

if 表达式

// if 作为表达式,可以返回值
val max = if (a > b) a else b
// 多分支
val grade = if (score >= 90) {
"A"
} else if (score >= 80) {
"B"
} else if (score >= 60) {
"C"
} else {
"F"
}

when 表达式

// 类似 switch,但更强大
val result = when (x) {
1 -> "One"
2 -> "Two"
3, 4 -> "Three or Four"
in 5..10 -> "Between 5 and 10"
else -> "Unknown"
}
// 无参数的 when
val description = when {
x < 0 -> "Negative"
x == 0 -> "Zero"
x > 0 -> "Positive"
else -> "Unknown"
}
// 类型检查
fun describe(obj: Any): String = when (obj) {
is Int -> "Integer: $obj"
is String -> "String of length ${obj.length}"
is List<*> -> "List of size ${obj.size}"
else -> "Unknown type"
}

循环

// for 循环
for (i in 1..5) {
println(i) // 1, 2, 3, 4, 5
}
for (i in 5 downTo 1) {
println(i) // 5, 4, 3, 2, 1
}
for (i in 0 until 5) {
println(i) // 0, 1, 2, 3, 4 (不包含5)
}
for (i in 0..10 step 2) {
println(i) // 0, 2, 4, 6, 8, 10
}
// 遍历集合
val list = listOf("a", "b", "c")
for (item in list) {
println(item)
}
// 带索引遍历
for ((index, value) in list.withIndex()) {
println("$index: $value")
}
// while 循环
var count = 0
while (count < 5) {
println(count)
count++
}

集合

List

// 不可变列表
val list = listOf(1, 2, 3)
// list.add(4) // Error - 没有 add 方法
// 可变列表
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4)
mutableList.remove(1)
// 常用操作
list.size
list.isEmpty()
list.first()
list.last()
list[0]
list.contains(2)
list.indexOf(2)

Set

// 不可变集合
val set = setOf(1, 2, 3, 3) // {1, 2, 3}
// 可变集合
val mutableSet = mutableSetOf(1, 2, 3)
mutableSet.add(4)
mutableSet.remove(1)

Map

// 不可变 Map
val map = mapOf("a" to 1, "b" to 2)
println(map["a"]) // 1
// 可变 Map
val mutableMap = mutableMapOf("a" to 1, "b" to 2)
mutableMap["c"] = 3
mutableMap.remove("a")
// 遍历
for ((key, value) in map) {
println("$key -> $value")
}

集合操作

val numbers = listOf(1, 2, 3, 4, 5)
// 转换
numbers.map { it * 2 } // [2, 4, 6, 8, 10]
numbers.filter { it > 2 } // [3, 4, 5]
numbers.filterNot { it > 2 } // [1, 2]
// 查找
numbers.find { it > 3 } // 4 (第一个匹配)
numbers.firstOrNull { it > 10 } // null
numbers.any { it > 3 } // true
numbers.all { it > 0 } // true
numbers.none { it < 0 } // true
// 聚合
numbers.sum() // 15
numbers.average() // 3.0
numbers.max() // 5
numbers.min() // 1
numbers.count { it > 2 } // 3
// 其他
numbers.sorted() // [1, 2, 3, 4, 5]
numbers.sortedDescending() // [5, 4, 3, 2, 1]
numbers.reversed() // [5, 4, 3, 2, 1]
numbers.distinct() // 去重
numbers.take(3) // [1, 2, 3]
numbers.drop(2) // [3, 4, 5]
numbers.chunked(2) // [[1, 2], [3, 4], [5]]
// 链式操作
numbers
.filter { it > 1 }
.map { it * 2 }
.sorted()
// [4, 6, 8, 10]

类与对象

基本类

class Person(val name: String, var age: Int) {
// 次构造函数
constructor(name: String) : this(name, 0)
// 方法
fun introduce() {
println("I'm $name, $age years old.")
}
}
val person = Person("Alice", 25)
println(person.name) // Alice
person.age = 26
person.introduce()

init 块

class Person(val name: String) {
val nameLength: Int
init {
println("Person created: $name")
nameLength = name.length
}
}

数据类

// 自动生成 equals, hashCode, toString, copy, componentN
data class User(val name: String, val age: Int)
val user1 = User("Alice", 25)
val user2 = User("Alice", 25)
println(user1 == user2) // true
println(user1.toString()) // User(name=Alice, age=25)
// copy 函数
val user3 = user1.copy(age = 26) // User(name=Alice, age=26)
// 解构声明
val (name, age) = user1
println("$name is $age years old")

单例对象

// object 声明单例
object Database {
val url = "jdbc:mysql://localhost:3306/mydb"
fun connect() {
println("Connecting to $url")
}
}
Database.connect()
// 伴生对象(类似 Java 的静态成员)
class MyClass {
companion object {
const val TAG = "MyClass"
fun create(): MyClass {
return MyClass()
}
}
}
println(MyClass.TAG)
val instance = MyClass.create()

继承

// 默认类是 final,需要 open 关键字允许继承
open class Animal(val name: String) {
open fun speak() {
println("$name makes a sound")
}
}
class Dog(name: String, val breed: String) : Animal(name) {
override fun speak() {
println("$name barks")
}
fun fetch() {
println("$name fetches the ball")
}
}
val dog = Dog("Buddy", "Golden Retriever")
dog.speak() // Buddy barks

接口

interface Drawable {
fun draw()
// 可以有默认实现
fun describe() {
println("This is drawable")
}
}
interface Clickable {
fun click()
}
// 实现多个接口
class Button : Drawable, Clickable {
override fun draw() {
println("Drawing button")
}
override fun click() {
println("Button clicked")
}
}

抽象类

abstract class Shape {
abstract fun area(): Double
abstract fun perimeter(): Double
fun describe() {
println("Area: ${area()}, Perimeter: ${perimeter()}")
}
}
class Circle(val radius: Double) : Shape() {
override fun area() = Math.PI * radius * radius
override fun perimeter() = 2 * Math.PI * radius
}

密封类

// 密封类限制子类的类型
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
object Loading : Result()
}
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Data: ${result.data}")
is Result.Error -> println("Error: ${result.message}")
is Result.Loading -> println("Loading...")
// 不需要 else,编译器知道所有情况
}
}

作用域函数

Kotlin 提供了 5 个作用域函数:let、run、with、apply、also。

let

// 常用于空安全检查和转换
val name: String? = "Kotlin"
name?.let {
println(it.uppercase()) // KOTLIN
}
// 链式转换
val result = "hello"
.let { it.uppercase() }
.let { "$it!" }
println(result) // HELLO!

run

// 对象配置 + 计算结果
val result = "hello".run {
println(this)
uppercase() // 返回值
}
println(result) // HELLO
// 无接收者的 run
val hexString = run {
val digits = "0123456789ABCDEF"
digits.take(6)
}

with

// 对已有对象进行多次操作
val numbers = mutableListOf(1, 2, 3)
val result = with(numbers) {
add(4)
add(5)
"List has $size elements" // 返回值
}
println(result) // List has 5 elements

apply

// 对象配置,返回对象本身
val person = Person("Alice", 25).apply {
age = 26
}
// 常用于构建器模式
val intent = Intent().apply {
action = "com.example.ACTION"
putExtra("key", "value")
}

also

// 附加操作,返回对象本身
val numbers = mutableListOf(1, 2, 3).also {
println("List created with ${it.size} elements")
}
// 用于调试链式调用
val result = numbers
.also { println("Before: $it") }
.map { it * 2 }
.also { println("After: $it") }

选择指南

函数对象引用返回值使用场景
letitLambda 结果空安全检查、转换
runthisLambda 结果对象配置 + 计算
withthisLambda 结果对已有对象操作
applythis对象本身对象初始化配置
alsoit对象本身附加效果、调试

异常处理

fun divide(a: Int, b: Int): Int {
if (b == 0) {
throw IllegalArgumentException("除数不能为零")
}
return a / b
}
// try-catch
try {
val result = divide(10, 0)
println(result)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
} finally {
println("Done")
}
// try 作为表达式
val result = try {
divide(10, 2)
} catch (e: Exception) {
0
}

协程基础

协程是 Kotlin 的轻量级线程,用于简化异步编程。

基本使用

import kotlinx.coroutines.*
fun main() = runBlocking {
// 启动协程
launch {
delay(1000) // 非阻塞延迟
println("World!")
}
println("Hello,")
}
// 输出: Hello, (等待1秒) World!

async/await

import kotlinx.coroutines.*
suspend fun fetchUser(): String {
delay(1000)
return "Alice"
}
suspend fun fetchEmail(): String {
delay(1000)
return "alice@example.com"
}
fun main() = runBlocking {
// 并行执行
val userDeferred = async { fetchUser() }
val emailDeferred = async { fetchEmail() }
val user = userDeferred.await()
val email = emailDeferred.await()
println("$user - $email") // 总共约1秒,而非2秒
}

suspend 函数

// suspend 函数只能在协程或其他 suspend 函数中调用
suspend fun loadData(): String {
return withContext(Dispatchers.IO) {
// 在 IO 线程执行
"Data loaded"
}
}

下一步

学习了 Kotlin 基础后,可以继续学习:

  • Android 开发:Jetpack Compose、Android Architecture Components
  • 后端开发:Ktor、Spring Boot with Kotlin
  • 跨平台开发:Kotlin Multiplatform (KMP)
  • 官方文档:kotlinlang.org

Read Next

Dart 语言基础

Read Previous

晒太阳的健康益处