Kotlin: Kotlin基础语法详解

最后更新:2026-08-26

Kotlin 的语法设计哲学:能用表达式就不用语句,能省的代码绝不多写一行。这让 Alice 写出的代码比 Java 短 40% 却表达更多。

1. 你将学到


2. 一个开发者的真实故事

(1) 痛点:可变状态引发的并发 Bug

Alice 在 OrderProcessor 中用 定义了共享的订单计数器,在高并发下出现数据竞争,导致计数结果偏差 2%——百万级订单下就是 20,000 笔差异。

(2) 不可变优先的解法

KOTLIN
// BAD: mutable shared state
var orderCount = 0  // Race condition!

// GOOD: immutable + functional pipeline
val processedOrders = orders
    .filter { it.status == "CONFIRMED" }
    .also { println("Processed ${it.size} orders") }

不可变数据天然线程安全, 是 Kotlin 程序员的第一选择, 是最后手段。


3. val 与 var:不可变优先

(1) 基本语法

KOTLIN
// val: read-only (immutable reference) - PREFERRED
val orderId = "ORD-001"         // Type inferred as String
val total: Double = 299.99      // Explicit type

// var: mutable (reassignable) - USE SPARINGLY
var status = "PENDING"          // Can be reassigned
status = "CONFIRMED"            // OK

// val does NOT mean the object is immutable
val items = mutableListOf`<Order>`()  // Reference is val, list is mutable
items.add(Order("ORD-002", 150.0, "NEW"))  // OK - modifying the list
// items = mutableListOf()  // ERROR - cannot reassign val

(2) val vs var 对比

维度
重新赋值 不允许 允许
线程安全 引用不可变,天然安全 需同步保护
推荐度 首选 最后手段
类比 Java Java 普通变量
底层 只读引用(对象可能可变) 可变引用

4. 字符串模板

(1) 基础模板

KOTLIN
val orderId = "ORD-001"
val total = 299.99

// Simple variable reference
println("Order: $orderId")

// Expression in template
println("Total: \$$total USD")
println("Tax: \$${total * 0.08} USD")

// Arbitrary expression with ${}
val items = listOf("Widget", "Gadget")
println("Item count: ${items.size}, First: ${items[0]}")

(2) 多行字符串(raw string)

KOTLIN
val receipt = """
    |Order ID: ORD-001
    |Total: $299.99 USD
    |Status: CONFIRMED
""".trimMargin()

// Alternative: trimIndent
val json = """
    {
      "order_id": "ORD-001",
      "total": 299.99
    }
""".trimIndent()

(3) 字符串模板对比

特性 Java Kotlin
变量引用
表达式
多行 无原生支持
缩进处理 手动 /

5. when 表达式

是 的全面升级版——它是表达式,有返回值,能匹配类型、范围和任意条件。

(1) 基础用法

KOTLIN
// when as expression (must be exhaustive)
val status = "CONFIRMED"
val label = when (status) {
    "PENDING" -> "Waiting for payment"
    "CONFIRMED" -> "Payment received"
    "SHIPPED" -> "In transit"
    "CANCELLED" -> "Order cancelled"
    else -> "Unknown status"
}

(2) 高级匹配

KOTLIN
// Multiple values
when (status) {
    "PENDING", "NEW" -> processNewOrder()
    in listOf("CONFIRMED", "PAID") -> shipOrder()
    else -> handleOther()
}

// Range matching
val quantity = 150
when (quantity) {
    in 1..10 -> println("Small order")
    in 11..100 -> println("Medium order")
    in 101..1_000 -> println("Large order")
    else -> println("Bulk order")
}

// Type matching
fun describe(obj: Any): String = when (obj) {
    is String -> "String of length ${obj.length}"
    is Int -> "Integer: $obj"
    is List<*> -> "List with ${obj.size} elements"
    else -> "Unknown type"
}

(3) when 分支决策树

100%
flowchart LR
    A[when status] --> B["PENDING, NEW"]
    A --> C["CONFIRMED, PAID"]
    A --> D["SHIPPED"]
    A --> E["CANCELLED"]
    A --> F[else]
    B --> B1[processNewOrder]
    C --> C1[shipOrder]
    D --> D1[trackShipment]
    E --> E1[refundOrder]
    F --> F1[handleOther]

(4) when vs switch 对比

维度 Java switch Kotlin when
返回值 语句,无返回值 表达式,有返回值
多值匹配 需要 case 穿透
范围匹配 不支持
类型匹配 不支持
守卫条件 不支持
穷尽检查 编译器强制(表达式模式)

6. 区间与迭代

(1) 区间操作符

KOTLIN
// Closed range: includes both ends
for (i in 1..5) print("$i ")  // 1 2 3 4 5

// Half-open range: excludes end
for (i in 1 until 5) print("$i ")  // 1 2 3 4

// Step
for (i in 1..10 step 2) print("$i ")  // 1 3 5 7 9

// DownTo
for (i in 5 downTo 1) print("$i ")  // 5 4 3 2 1

// Char range
for (c in 'A'..'E') print("$c ")  // A B C D E

(2) 集合迭代

KOTLIN
val orders = listOf(
    Order("ORD-001", 299.99),
    Order("ORD-002", 1_500.00),
    Order("ORD-003", 45.50)
)

// Iterate with index
for ((index, order) in orders.withIndex()) {
    println("[$index] ${order.id}: \$${order.total} USD")
}

// Iterate map
val statusMap = mapOf("ORD-001" to "SHIPPED", "ORD-002" to "PENDING")
for ((id, status) in statusMap) {
    println("$id -> $status")
}

(3) 区间操作符速查

操作符 含义 示例 结果
闭区间 1,2,3,4,5
半开区间 1,2,3,4
步长 1,4,7,10
递减 5,4,3,2,1
包含检查 true

7. 表达式体函数与代码习惯

(1) 表达式体函数

KOTLIN
// Block body
fun calculateTax(total: Double): Double {
    return total * 0.08
}

// Expression body (more concise)
fun calculateTax(total: Double): Double = total * 0.08

// Type inference with expression body
fun calculateTax(total: Double) = total * 0.08

(2) Kotlin 代码习惯

KOTLIN
// 1. Semicolons are optional
val x = 1  // No semicolon needed

// 2. Trailing lambda convention
orders.filter { it.total > 1_000 }  // lambda outside parens

// 3. It keyword for single-parameter lambda
orders.map { it.id }  // 'it' = implicit parameter

// 4. String template over concatenation
val msg = "Order $orderId confirmed"  // Not "Order " + orderId + " confirmed"

// 5. Expression body for simple functions
fun isHighValue(order: Order) = order.total > 10_000

(3) Java vs Kotlin 习惯对比

习惯 Java Kotlin
分号 必须 可选
字符串拼接 运算符 模板
简单函数 块体 表达式体
Lambda 位置 参数内 尾部括号外
单参数 Lambda 命名参数 关键字

8. 完整示例:OrderProcessor 订单分流

KOTLIN
// ============================================
// OrderProcessor - Order Routing Engine
// Feature: Route orders based on status and value
// ============================================

data class Order(val id: String, val total: Double, val status: String)

fun routeOrder(order: Order): String = when {
    order.status == "CANCELLED" -> "REFUND_QUEUE"
    order.total > 10_000 -> "VIP_PIPELINE"
    order.total > 1_000 -> "PRIORITY_PIPELINE"
    order.status == "CONFIRMED" -> "STANDARD_PIPELINE"
    order.status in listOf("PENDING", "NEW") -> "WAITING_QUEUE"
    else -> "MANUAL_REVIEW"
}

fun processBatch(orders: List`<Order>`) {
    for ((index, order) in orders.withIndex()) {
        val pipeline = routeOrder(order)
        val priority = when (pipeline) {
            "VIP_PIPELINE" -> "CRITICAL"
            "PRIORITY_PIPELINE" -> "HIGH"
            "STANDARD_PIPELINE" -> "NORMAL"
            else -> "LOW"
        }
        println("[${index + 1}] ${order.id} -> $pipeline (Priority: $priority)")
    }
}

fun main() {
    val orders = listOf(
        Order("ORD-001", 299.99, "CONFIRMED"),
        Order("ORD-002", 15_000.00, "CONFIRMED"),
        Order("ORD-003", 2_500.00, "PENDING"),
        Order("ORD-004", 45.50, "CANCELLED"),
        Order("ORD-005", 750.00, "NEW")
    )

    println("=== Order Routing Report ===")
    processBatch(orders)

    // Summary with functional pipeline
    val pipelineCounts = orders
        .map { routeOrder(it) }
        .groupingBy { it }
        .eachCount()

    println("\n=== Pipeline Distribution ===")
    for ((pipeline, count) in pipelineCounts) {
        println("  $pipeline: $count orders")
    }
}

输出:

TEXT 📖 仅展示
=== Order Routing Report ===
[1] ORD-001 -> STANDARD_PIPELINE (Priority: NORMAL)
[2] ORD-002 -> VIP_PIPELINE (Priority: CRITICAL)
[3] ORD-003 -> PRIORITY_PIPELINE (Priority: HIGH)
[4] ORD-004 -> REFUND_QUEUE (Priority: LOW)
[5] ORD-005 -> WAITING_QUEUE (Priority: LOW)

=== Pipeline Distribution ===
  STANDARD_PIPELINE: 1 orders
  VIP_PIPELINE: 1 orders
  PRIORITY_PIPELINE: 1 orders
  REFUND_QUEUE: 1 orders
  WAITING_QUEUE: 1 orders

❓ 常见问题

Q val 定义的集合能修改内容吗?
A 能。val 只保证引用不变,集合内容仍然可以修改。需要真正不可变集合请使用 而非 。
Q when 表达式必须写 else 吗?
A 当 when 作为表达式使用时,编译器要求穷尽所有分支,否则必须写 else。当 when 作为语句使用时,else 可选。
Q 和 一样吗?
A 效果一样,但语义不同。 表示"从 1 到 5(含)", 表示"从 1 到 6 之前"。遍历列表索引时 更常用。
Q 表达式体函数什么时候该用?
A 函数体是单个表达式时用表达式体,超过 2 行逻辑时用块体。可读性是第一原则。
Q 字符串模板中 和 有什么区别?
A 只能引用简单变量名; 可以包含任意表达式,如 或 。
Q when 可以匹配浮点数范围吗?
A 技术上可以,但浮点数精度问题可能导致意外结果。建议用整数范围或显式比较。

▶ 示例:val 与 var

KOTLIN
val name = "Alice"  // 不可变
var age = 30        // 可变
age = 31            // OK
// name = "Bob"     // 编译错误

输出:

TEXT 📖 仅展示
编译通过;name 重新赋值失败

▶ 示例:when 表达式

KOTLIN
val score = 85
val grade = when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    else -> "C"
}
println(grade)

输出:

TEXT 📖 仅展示
B

▶ 示例:for 循环

KOTLIN
for (i in 1..3) println(i)
for (s in listOf("a", "b")) println(s)

输出:

TEXT 📖 仅展示
1
2
3
a
b

📖 小节


📝 作业

  1. 基础题(难度⭐):用 和字符串模板编写一个函数,输出订单摘要 。提示:
  2. 进阶题(难度⭐⭐):用 表达式实现一个折扣计算器:金额 > 10,000 打 8 折,> 5,000 打 9 折,其余不打折。提示: 守卫条件
  3. 挑战题(难度⭐⭐⭐):用区间和 实现一个税费阶梯计算器,不同收入区间适用不同税率。提示:

← 上一课 | 下一课 →

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏