Kotlin 实战指南

FreeGuideOnline 最新 2026-07-15

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


点击左侧绿色运行按钮,控制台将输出 `Hello, Kotlin!`。

---

## 基本语法

### 变量与类型推断

Kotlin 使用 `val` 声明只读变量(类似 Java 的 `final`),`var` 声明可变变量。

```kotlin
val name = "Alice"           // 类型自动推断为 String
var age = 25                 // 类型为 Int
// name = "Bob"              // 编译错误,val 不可重新赋值
age = 26                     // 正确

也可以显式指定类型:

val greeting: String = "Hello"
val count: Int = 10

基本数据类型

Kotlin 中一切皆对象,没有原始类型(但编译后会优化为 JVM 原始类型)。

类型 示例
Int 42
Long 42L
Double 3.14
Float 3.14f
Char 'A'
String "Kotlin"
Boolean true / false

字符串模板让变量的嵌入非常方便:

val name = "Kotlin"
println("Hello, $name!")   // 输出 Hello, Kotlin!
println("Result: ${1 + 2}") // 表达式需要用大括号

控制流

if 表达式

与许多语言不同,if 是表达式,可以直接返回值:

val max = if (a > b) a else b

when 表达式

取代 Java 的 switch,功能更强大:

when (x) {
    1 -> println("x is 1")
    2, 3 -> println("x is 2 or 3")
    in 4..10 -> println("x is in range")
    is Int -> println("x is int")
    else -> println("unknown")
}

循环

for 循环可以直接遍历任何可迭代对象:

val items = listOf("apple", "banana", "kiwi")
for (item in items) {
    println(item)
}

// 遍历区间
for (i in 1..5) {
    println(i)
}
// 带步长
for (i in 6 downTo 1 step 2) {
    println(i) // 6,4,2
}

函数定义

使用 fun 关键字,参数格式为 name: Type,返回类型写在后面:

fun sum(a: Int, b: Int): Int {
    return a + b
}

当函数体是单个表达式时,可简写为:

fun sum(a: Int, b: Int) = a + b

默认参数和具名参数

fun greet(name: String = "Guest", greeting: String = "Hello") {
    println("$greeting, $name")
}

greet()                     // Hello, Guest
greet("Tom")                // Hello, Tom
greet(greeting = "Hi")      // Hi, Guest
greet("Tom", "Welcome")     // Welcome, Tom

高阶函数与 Lambda

Kotlin 支持将函数作为参数或返回值:

fun <T> List<T>.customFilter(predicate: (T) -> Boolean): List<T> {
    val result = mutableListOf<T>()
    for (item in this) {
        if (predicate(item)) result.add(item)
    }
    return result
}

val numbers = listOf(1, 2, 3, 4, 5)
val even = numbers.customFilter { it % 2 == 0 }
println(even) // [2, 4]

空安全

Kotlin 的类型系统防止 null 滥用。

普通类型不可为 null:

var name: String = "Bob"
// name = null  // 编译错误

若要允许 null,使用 ?

var nullableName: String? = "Alice"
nullableName = null    // 正确

安全调用 ?. 会在对象为 null 时返回 null 而不是抛出异常:

val length = nullableName?.length // 若 nullableName 为 null,则 length 为 null

Elvis 操作符 ?: 提供默认值:

val len = nullableName?.length ?: 0

强制调用 !! 断言非空(不推荐,除非确定不为空):

val forced = nullableName!!.length // 若 null 则抛出异常

面向对象

类与继承

Kotlin 中类默认是 public final 的(不可继承),想要可继承需要用 open 修饰。

open class Animal(val name: String) {
    open fun sound() = "Animal sound"
}

class Dog(name: String, val breed: String) : Animal(name) {
    override fun sound() = "Woof!"
}

属性与访问器

属性可以直接在构造函数中声明,自动生成 getter/setter。

class Person {
    var age: Int = 0
        set(value) {
            if (value >= 0) field = value
        }

    val isAdult: Boolean
        get() = age >= 18
}

数据类

专用于保存数据的类,自动生成 equals(), hashCode(), toString(), copy() 等。

data class User(val id: Int, val name: String)

val user1 = User(1, "Alice")
println(user1)  // User(id=1, name=Alice)
val user2 = user1.copy(name = "Bob")

伴生对象与单例

通过 companion object 实现类似静态成员:

class MyClass {
    companion object {
        const val TAG = "MyClass"
        fun create() = MyClass()
    }
}

val instance = MyClass.create()

直接使用 object 关键字声明单例:

object Config {
    val baseUrl = "https://api.example.com"
}

扩展函数

在不修改原始类的情况下为其添加新函数:

fun String.removeFirstLast(): String =
    this.substring(1, this.length - 1)

println("Hello".removeFirstLast()) // ell

集合与函数式编程

Kotlin 标准库为集合提供了丰富的函数式操作,包括 filter, map, flatMap, groupBy 等。

val names = listOf("Alice", "Bob", "Charlie", "David")

// 过滤并转换
val result = names
    .filter { it.length > 3 }
    .map { it.uppercase() }

println(result)  // [ALICE, CHARLIE]

使用序列优化链式操作(惰性求值):

val largeList = (1..1_000_000).toList()
val evenDoubled = largeList.asSequence()
    .filter { it % 2 == 0 }
    .map { it * 2 }
    .take(10)
    .toList()

常用集合类型

  • List: 有序,可重复,listOf("a","b")
  • Set: 无序,不重复,setOf(1,2,3)
  • Map: 键值对,mapOf("key" to "value")

可变版本:mutableListOf, mutableSetOf, mutableMapOf


协程入门

Kotlin 协程提供了一种更简洁的方式处理异步任务,不阻塞线程。

添加依赖

build.gradle.kts 中添加:

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}

启动协程

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000L)
        println("World!")
    }
    println("Hello,")
    // 输出: Hello, 等 1 秒后打印 World!
}

结构化并发

协程作用域确保子协程的完成:

suspend fun fetchUser(): String {
    delay(500) // 模拟网络请求
    return "User"
}

fun main() = runBlocking {
    val user = async { fetchUser() }
    println("Result: ${user.await()}")
}

实战:并发请求

suspend fun fetchData(id: Int): String {
    delay(1000) // 模拟耗时
    return "Data-$id"
}

fun main() = runBlocking {
    val deferreds = (1..5).map { async { fetchData(it) } }
    val results = deferreds.awaitAll()
    println(results)
}

实战:构建一个简单的命令行待办事项应用

接下来,我们将综合运用上述知识,创建一个命令行待办事项管理器。

需求

  • 添加任务
  • 列出所有任务
  • 标记任务完成
  • 退出

代码实现

import java.util.*

data class Task(
    val id: UUID = UUID.randomUUID(),
    val title: String,
    var isCompleted: Boolean = false
)

object TaskManager {
    private val tasks = mutableListOf<Task>()

    fun add(title: String) {
        tasks.add(Task(title = title))
    }

    fun list() {
        tasks.forEachIndexed { index, task ->
            val status = if (task.isCompleted) "[x]" else "[ ]"
            println("${index + 1}. $status ${task.title}")
        }
    }

    fun complete(index: Int) {
        if (index in 1..tasks.size) {
            tasks[index - 1].isCompleted = true
        } else {
            println("Invalid task number.")
        }
    }
}

fun main() {
    val scanner = Scanner(System.`in`)
    while (true) {
        println("\n--- TODO ---")
        println("1. Add Task")
        println("2. List Tasks")
        println("3. Complete Task")
        println("4. Exit")
        print("Choose: ")
        when (scanner.nextLine()) {
            "1" -> {
                print("Enter task: ")
                val title = scanner.nextLine()
                TaskManager.add(title)
            }
            "2" -> TaskManager.list()
            "3" -> {
                print("Enter task number to complete: ")
                val num = scanner.nextLine().toIntOrNull()
                if (num != null) TaskManager.complete(num)
                else println("Invalid input.")
            }
            "4" -> return
            else -> println("Invalid choice.")
        }
    }
}