KOTLIN CORE · 107
Syntax、Types、Functions:不要重學「程式設計」,而是重新映射概念
到這裡你已經知道 value、type、if、function、state。Kotlin 不是把這些概念重來一次;真正要學的是它如何用更嚴格的型別、expression 與 null-safety 語法表達同樣的程式問題。
Why now:Kotlin 在這個平台扮演什麼角色?
.kt source→ Kotlin compiler →bytecode / platform output→ JVM / Android Runtime →process / app
在 Android 路線裡,Kotlin source 通常不是像 Browser JavaScript 那樣直接下載後執行。它先經過 build toolchain,最後由 Android runtime 執行 app code。
Learning outcomes
- 能把 JavaScript/C++ 已知概念映射到 Kotlin 的
val、var、type、function。 - 能解釋
val不等於「object 完全不可變」。 - 能把
if/when當 expression 使用。 - 能設計一個小型 typed domain function。
1. val / var:控制的是 reference 能不能重新指定
val tripId = "trip-001"
// tripId = "trip-002" // compile error
var distanceKm = 0.0
distanceKm = 1.25
val 表示這個名稱之後不能指向另一個值;var 可以重新 assignment。
但不要誤解:
val 不代表 object 內部一定 immutable。例如 val list = mutableListOf(1) 仍可以 list.add(2)。2. Type inference 與 explicit types
val speed = 30.5 // inferred Double
val active = true // inferred Boolean
val elapsedSeconds: Long = 120
val label: String = "Running"
和 TypeScript 一樣,不需要每個地方都重複寫 type。重要 boundary / public API / 容易誤解的型別才值得明確標示。
3. Function contract
fun calculateAverageSpeed(
distanceKm: Double,
elapsedSeconds: Long
): Double {
if (elapsedSeconds == 0L) return 0.0
val hours = elapsedSeconds / 3600.0
return distanceKm / hours
}
arguments→ typed parameters →body→Double return value
4. if 在 Kotlin 是 expression
val status =
if (distanceKm > 0.0) {
"moving"
} else {
"idle"
}
它不是只能做 control statement,也能直接產生一個 value。
5. when:把多分支規則集中表達
fun paceLabel(speedKmh: Double): String =
when {
speedKmh >= 80 -> "fast"
speedKmh >= 40 -> "medium"
speedKmh > 0 -> "slow"
else -> "stopped"
}
它很像更有表達力的多分支 expression。重點仍是規則順序與 boundary。
6. Project checkpoint:Trip Meter Domain Core v1
data class TripSnapshot(
val distanceKm: Double,
val elapsedSeconds: Long
)
fun averageSpeed(snapshot: TripSnapshot): Double {
if (snapshot.elapsedSeconds == 0L) return 0.0
val hours = snapshot.elapsedSeconds / 3600.0
return snapshot.distanceKm / hours
}
fun statusOf(snapshot: TripSnapshot): String =
when {
snapshot.elapsedSeconds == 0L -> "ready"
snapshot.distanceKm == 0.0 -> "waiting"
else -> "moving"
}
這個 domain core 還沒有 Android UI、GPS、permission。這是刻意的:先讓 business logic 可以脫離 platform 被理解與測試。
7. Debug evidence:compile error 和 business rule error
val elapsedSeconds: Long = "120"
// type mismatch:compile-time evidence
val hours = elapsedSeconds / 3600
// 若兩邊都是整數,會先做整數除法,可能造成 logic error
即使型別正確,運算規則仍可能錯;static typing 不是 logic correctness 的替代品。
Knowledge check
val和 object immutability 為什麼不是同一件事?- 把
statusOf()加入"finished"狀態,你需要新增哪個 input? - 為什麼 domain logic 先不放 Activity / ViewModel 裡?
- 把一個 JavaScript function 改寫成 Kotlin,逐項對照 parameter / return / branch。