我是音葵

FOX4

平时我的任务很简单。

确认目标

分析环境

执行任务

不过今天的目标稍微有点特殊。

不是敌人。

也不是任务区域。

而是——

Kotlin

如果你还把 Kotlin 理解成“Android 上比较好用的 Java 替代品”,那么这份情报已经有点过时了。

现在是 2026 年

目前 Kotlin 的稳定版本已经来到 2.4.20。Kotlin 的发展重点,也早就不只是在 Android 上继续优化语法,而是在向多平台、现代工具链、WebAssembly,以及 AI 辅助开发等方向继续扩展。

所以这次,我想从自己的角度,重新整理一下:

现在的 Kotlin,到底是什么?


一、首先,Kotlin 到底是什么?

如果一定要用一句话说明:

Kotlin 是一门现代、静态类型的编程语言,并且正在发展成为覆盖 JVM、Android、iOS、桌面、服务器、JavaScript 和 WebAssembly 等环境的多平台语言生态。

以前大家想到 Kotlin,通常是:

Kotlin
   ↓
Android

这个印象并没有错。

Android 依然是 Kotlin 最重要的应用领域之一。

但现在已经不能只这样理解。

Kotlin 的战场正在逐渐变成:

                    Kotlin
                       │
       ┌─────────┼─────────┐
       ↓               ↓               ↓
    Android          Server          Desktop
       │               │               │
   Compose          JVM/Jakarta      Compose
       │
       └──────┐
                   ↓
          Kotlin Multiplatform
             /       |       \
          Android   iOS     Desktop
                       \
                        Web / Wasm

Kotlin 官方 2026 年的报告显示,全球已有约 810 万有 Kotlin 使用经验的开发者;超过一半的 Kotlin 开发者将它用于后端任务,超过三成参与 Multiplatform 项目。官方也明确把后端、多平台和 AI 视为 Kotlin 当前增长的重要方向。

所以……

如果以前的 Kotlin 像是一支主要负责 Android 任务的小队。

现在,它正在扩大自己的任务范围。


二、为什么我会喜欢 Kotlin?

我第一次认真看 Kotlin 的时候,最先注意到的并不是它有多少功能。

而是:

它很干净

例如:

val name = "Otogi"

就这样。

已经足够了。

当然,如果你希望明确写出类型,也可以:

val name: String = "Otogi"

但很多时候,编译器已经知道:

name
↓
String

那就没有必要重复说明。

这和执行任务其实很像。

如果情报已经确认:

目标:FOX4

我没有必要再写一份:

目标类型:人物
目标名称:FOX4
目标是否存在:是

……

很浪费时间。

Kotlin 的很多设计都体现了类似的思路:

如果编译器能够可靠地判断,就不要让开发者重复表达。

这也是我认为 Kotlin 很舒服的地方。


三、val 和 var:不是所有东西都需要变化

Kotlin 有两个非常基础的变量关键字:

val
var

例如:

val mission = "FOX Operation"

var ammo = 10

val 表示变量不能重新赋值。

var 则允许重新赋值。

所以:

val mission = "FOX Operation"

任务确定之后,就不要随便改变。

而:

var ammo = 10

ammo = 9

弹药数量当然可以随着任务推进发生变化。

这看起来只是一个小小的语法区别。

实际上,它涉及一个非常重要的工程原则:

减少不必要的可变状态。

如果一个变量可以不改变,那么就让它保持不变。

所以我的习惯是:

默认 val
必要时才 var

状态越少变化,程序就越容易理解。

任务也一样。

能固定的东西,就不要让它到处乱跑。


四、空安全:先确认目标,再执行操作

如果你以前写过 Java,大概见过这个:

NullPointerException

简称:

NPE

嗯……

我不喜欢它。

Kotlin 对这个问题的处理方式很直接。

例如:

val target: String? = null

注意这里的:

?

它表示:

target 可能为空。

所以你不能直接:

println(target.length)

Kotlin 会阻止你。

你需要明确地写:

println(target?.length)

意思就是:

目标存在?
    │
    ├── 是 → 获取 length
    │
    └── 否 → 返回 null

这其实非常合理。

如果连目标是否存在都没有确认,就直接开始执行下一步……

很危险

所以 Kotlin 干脆让类型系统帮你提前检查。


五、?::准备备用方案

有时候,目标不存在并不意味着任务必须终止。

例如:

val targetName = target ?: "Unknown"

如果 target 有值:

使用 target

如果没有:

使用 Unknown

这个:

?:

叫做 Elvis Operator。

名字有点奇怪。

不过很好用。

例如:

val nickname = profile?.nickname ?: "Anonymous"

意思就是:

profile 存在
    ↓
使用 nickname

profile 不存在
    ↓
使用 Anonymous

我喜欢这种写法。

因为它明确告诉程序:

正常情况是什么,备用方案又是什么。

不要把希望寄托在“应该不会发生异常”上。

真正可靠的系统,应该提前考虑异常情况。


六、data class:数据就应该只是数据

假设我要记录一个任务:

data class Mission(
    val id: Int,
    val target: String,
    val priority: Int
)

然后:

val mission = Mission(
    id = 4,
    target = "Unknown",
    priority = 10
)

如果任务优先级发生变化:

val emergencyMission = mission.copy(
    priority = 100
)

这样就可以得到一个新的对象。

原来的 mission 不需要被修改。

这对于现代应用开发非常重要。

尤其是:

State
  ↓
UI

这样的架构。

状态发生变化。

产生新的状态。

UI 根据新的状态进行更新。

而不是整个程序到处修改同一个对象。


七、Lambda:把“怎么做”交出去

Kotlin 的 Lambda 也是我很喜欢的功能。

例如现在有几个目标:

val targets = listOf(
    "Target-A",
    "Target-B",
    "Target-C"
)

我要筛选:

val selected = targets.filter {
    it.startsWith("Target")
}

我要转换:

val names = targets.map {
    "FOX-$it"
}

我要遍历:

targets.forEach {
    println(it)
}

这里的:

it

就是 Lambda 的默认参数。

所以:

targets.filter {
    it.startsWith("Target")
}

实际上就是:

“把所有目标交给我,我留下符合条件的。”

代码看起来几乎就是自然语言。

这就是 Lambda 很重要的地方:

把行为本身作为参数传递。


八、协程:等待,并不意味着什么都不做

接下来是现代 Kotlin 非常重要的一部分。

Coroutine

协程

假设我要从服务器获取任务:

suspend fun loadMission(): Mission {
    return api.getMission()
}

然后:

launch {
    val mission = loadMission()
    showMission(mission)
}

这里的:

suspend

非常重要

它表示这个函数可以在协程中挂起。

比如服务器还没有返回结果。

程序可以在挂起点暂停当前协程,而不是必须一直阻塞线程等待。

但有一点需要特别注意:

suspend 不等于自动创建线程,也不等于自动并发。

真正决定协程在哪里执行的,还包括:

CoroutineContext
Dispatcher
Scope

等等。

所以不要把:

suspend

理解成:

“这个函数自动跑到后台线程。”

不是这样的。

它更准确的含义是:

这个函数可以参与 Kotlin 的挂起式异步控制流。

如果用我的方式理解:

等待情报的时候,不代表必须一直站着占用资源。

等情报回来。

继续执行


九、Flow:持续接收情报

如果说:

suspend

更像:

“执行一次任务”

那么:

Flow

更像:

“持续接收情报”

例如一个 Repository 可以提供:

fun observeMission(): Flow<Mission> {
    return missionRepository.observeMission()
}

然后上层:

missionFlow.collect { mission ->
    println(mission)
}

Flow 可以用来表达持续变化的数据:

数据库变化
网络状态
用户输入
搜索结果
UI State
事件流

一个常见的现代 Android 数据流可能是:

Repository
     ↓
   Flow
     ↓
 ViewModel
     ↓
   State
     ↓
  Compose

这样看起来就很清楚。

数据从底层产生。

向上流动。

状态发生变化。

UI 响应变化。

这就是我理解的:

让情报沿着明确的路线流动。


十、Compose:不要告诉 UI“怎么改”,告诉它“应该是什么”

现在做 Android,如果还只按照传统 View 的思维来理解 UI,会越来越吃力。

现代 Android 开发的重要方向之一,就是:

Jetpack Compose

传统 UI 思路更像:

找到 View
    ↓
修改文字
    ↓
修改颜色
    ↓
修改 Visibility
    ↓
修改布局

Compose 则更接近:

@Composable
fun MissionScreen(
    mission: Mission
) {
    Column {
        Text("Target: ${mission.target}")
        Text("Priority: ${mission.priority}")
    }
}

我只需要描述:

当前状态下,界面应该是什么样。

当:

Mission

发生变化。

Compose 根据新的状态重新组合 UI。

所以思维方式从:

“我要怎么修改 UI?”

变成:

“现在这个状态下,UI 应该是什么?”

这其实是一种非常重要的变化。


十一、K2:2026 年不能绕开的关键词

如果你还停留在 Kotlin 1.x 时代的印象里,那么有一件事情需要更新。

K2

K2 是 Kotlin 新一代编译器架构。

现代 Kotlin 2.x 的很多语言能力、编译器能力以及工具链,都建立在 K2 的基础上。

Compose Multiplatform 也已经完成向 K2 编译器的迁移。

所以现在学习 Kotlin,不应该只关注:

语法有没有变化?

还应该关注:

编译器
IDE
Build Tool
插件
多平台工具链

这些东西其实决定了:

代码从“写出来”到“真正构建、测试、发布”的整个过程。

而 Kotlin 2.4.20 也继续在标准库、Kotlin/Native、Kotlin/Wasm、Kotlin/JS、Gradle 和编译器工具等方面进行更新。


十二、Kotlin Multiplatform:真正需要共享的东西,才共享

然后是我认为 2026 年非常值得关注的方向:

Kotlin Multiplatform,简称 KMP。

它的核心思想并不是:

“所有平台必须使用完全一样的代码。”

而是:

让开发者决定哪些代码应该共享

例如:

                Shared Kotlin
                     │
        ┌───────┼───────┐
        ↓            ↓           ↓
     Android        iOS        Desktop

适合共享的内容可以包括:

业务逻辑
数据模型
网络层
数据库
状态管理

而平台特有的内容:

Android API
iOS API
平台 UI
特殊硬件
平台服务

仍然可以保持独立。

所以我一直觉得:

KMP ≠ 100% 代码复用

更准确的是:

KMP =
合理共享
+
保留平台差异

Kotlin Multiplatform 本身已经是 Stable;官方当前支持状态中,Android、iOS、Desktop JVM 和 Server JVM 均为 Stable,而 Kotlin/Wasm Web 目前仍为 Beta。

这意味着:

KMP 已经不是“以后可能会有用”的实验技术

它已经可以进入真实生产项目。


十三、Compose Multiplatform:UI 也可以共享

如果 KMP 负责共享业务逻辑,那么 Compose Multiplatform 则进一步让 UI 共享成为可能。

例如:

@Composable
fun MissionPanel(
    mission: Mission
) {
    Column {
        Text("MISSION")
        Text(mission.target)
        Text("Priority: ${mission.priority}")
    }
}

同一套 Compose UI 思路,可以覆盖:

Android
iOS
Desktop

而 Web 方向则通过 Kotlin/Wasm 继续发展。

目前 Compose Multiplatform 在 Android、iOS 和 Desktop 上已经 Stable,Web/Wasm 仍然是 Beta。

所以如果现在有人告诉你:

“Compose Multiplatform 已经完全覆盖所有平台,而且所有地方都一样成熟”

……

情报不准确。

确认目标之后再行动

这是基本原则。

不同平台仍然会存在平台特有 API 和行为差异。官方文档也明确说明,有些平台 API 仍然需要放在平台特定代码中实现。


十四、Kotlin/Wasm:Kotlin 正在接近 Web 的另一条路线

还有一个值得观察的方向:

Kotlin/Wasm

它可以把 Kotlin 编译成 WebAssembly。

例如:

Kotlin
   ↓
Kotlin/Wasm
   ↓
WebAssembly
   ↓
Browser

配合 Compose Multiplatform,就可以让 Kotlin/Compose UI 进入 Web 环境。

而且现在已经可以直接创建 Kotlin/Wasm + Compose Multiplatform 的 Web 应用。

不过这里也要保持冷静。

目前 Kotlin/Wasm 仍然处于 Beta

所以我不会说:

“Web 已经是 Kotlin 的成熟主战场。”

更准确的说法是:

这是一个正在快速成熟、值得关注的方向。

对我来说,Beta 的意思就是:

可以侦察。
可以测试。
可以建立原型。
生产环境则要根据项目风险谨慎判断。

十五、2026 年,还有 AI

然后……

就是现在几乎所有开发者都无法绕开的话题。

AI

现在写代码已经越来越接近:

人类
 ↓
提出需求
 ↓
AI
 ↓
生成代码
 ↓
人类审查
 ↓
测试
 ↓
发布

所以现在学习 Kotlin,重点也在变化。

过去可能需要大量记忆:

API
语法
模板
代码写法

现在 AI 可以帮我们完成其中相当一部分。

但是有些东西,我不会交给 AI。

例如:

架构怎么设计?
状态应该放在哪里?
哪些代码应该共享?
哪里需要并发?
异常应该怎么处理?
这个抽象是不是过度了?
这个方案到底是不是正确的?

这些问题需要开发者自己判断。

所以我认为:

AI 会减少“写代码”的工作量,但不会自动减少“思考”的工作量。

甚至恰恰相反。

当生成代码变得越来越便宜之后:

判断代码是否值得存在,会越来越重要。


十六、AI 可以负责执行,但目标必须由我确认

如果一定要用任务来比喻……

AI 很像一个执行能力非常强的辅助单位。

你告诉它:

“把这个功能写出来。”

它可能很快就能给你一份代码。

但是:

“这个功能真的应该这样设计吗?”

这件事情还是需要有人负责。

所以我更愿意把 AI 放在这里:

        人类
          │
     确认目标
          │
          ↓
         AI
          │
     生成 / 修改
          │
          ↓
        测试
          │
          ↓
       人类审查

而不是:

人类
 ↓
AI
 ↓
直接发布

……

那太危险了。

目标都还没确认,就扣扳机?

不行。


十七、如果现在开始学习 Kotlin,我会怎么做?

如果是现在,也就是 2026 年,我不会建议你从头到尾背一本 Kotlin 语法大全。

我的路线会是:

Kotlin 基础
    ↓
空安全
    ↓
类与接口
    ↓
集合
    ↓
Lambda
    ↓
扩展函数
    ↓
Coroutine
    ↓
Flow
    ↓
Compose
    ↓
现代 Android 架构
    ↓
Kotlin Multiplatform
    ↓
Compose Multiplatform
    ↓
Kotlin/Wasm
    ↓
AI 辅助开发

然后——

做一个真正的项目。


十八、比如,做一个 FOX Mission Console

如果让我自己练习,我大概会做一个:

FOX Mission Console。

名字已经确定。

架构可以是:

                 Mission UI
                     │
                  Compose
                     │
              State / ViewModel
                     │
                Flow / Coroutine
                     │
                  Repository
                     │
              Shared Business
                     │
           Kotlin Multiplatform
               /      |      \
              /       |       \
         Android     iOS    Desktop
                              │
                              └── Web / Wasm

这个项目可以一次练习:

Kotlin
K2
Compose
Coroutine
Flow
State
网络请求
数据库
KMP
Compose Multiplatform
Wasm
AI 辅助开发

但最重要的不是技术栈列表。

而是:

你会真正遇到问题。

为什么状态没有更新?

为什么协程执行顺序和想象的不一样?

为什么 Flow 没有收到数据?

为什么共享代码反而让架构变复杂?

为什么这个平台必须写特殊实现?

为什么 AI 生成的代码看起来没问题,实际上却不合理?

这些问题,才是学习真正开始的地方。


十九、所以,2026 年还值得学 Kotlin 吗?

我的答案是:

值得

但不要只是为了:

“学会 Kotlin 语法”

如果目标只是:

会写变量
会写函数
会写 class

那么很快就会遇到瓶颈。

真正值得掌握的是 Kotlin 背后的思维:

空安全
不可变数据
函数式思维
结构化并发
响应式数据流
声明式 UI
模块化
跨平台架构
明确边界
AI 协作

这些思想并不只属于 Kotlin。

它们本身就是现代软件工程的一部分。


二十、最后

……

说了这么多。

如果一定要我总结 Kotlin,我会这样写:

少一点重复。
少一点状态。
少一点意外。
多一点明确。
多一点组合。
多一点自动化。

如果编译器能帮我检查。

就让编译器检查。

如果框架能帮我管理状态。

就交给框架。

如果 AI 能帮我生成重复代码。

就让 AI 去做。

但有一件事情不能省略。

确认目标

因为无论程序还是任务:

执行得再快,如果目标错了,也只是在更快地走向错误的结果。

所以我真正关心的,一直不是:

“这段代码能不能写出来?”

而是:

“这段代码应该存在吗?”

“它应该这样设计吗?”

“如果情况发生变化,它还能正常工作吗?”

这才是我理解的编程。

Kotlin 只是让我在完成这些事情的时候,少处理一些不必要的麻烦。

所以——

如果你准备开始学习 Kotlin。

不用想太多。

先写第一行代码。

fun main() {
    println("Mission Start.")
}

然后开始你的任务吧。

任务确认

Kotlin 入门任务,完成

—— FOX4 / 音葵