Kotlin 變數宣告:val 與 var
在 Kotlin 中,宣告變數主要使用兩個關鍵字:val 和 var。
這體現了 Kotlin 對於 不可變性 (Immutability) 的重視。
變數宣告語法
標準的變數宣告語法如下:
關鍵字 變數名稱: 型別 = 初始值
- 關鍵字:
val或var - 變數名稱:遵循 CamelCase (小駝峰) 命名法,例如
userName,isCompleted。 - 型別 (可選):如果可以從初始值推斷,可以省略。
- 初始值:如果不馬上賦值,則必須明確指定型別。
val (唯讀變數)
val 代表 Value (或是常數),全名是 read-only local variable。
一旦指派了初始值,就 不能再修改 (Reassign)。這等同於 Java 的 final 變數。
val name = "Miko"
// name = "Jason" // 錯誤!val 不能重新賦值
為什麼要優先使用 val?
- 可預測性:你永遠知道
val變數的值不會在其他地方被偷偷改掉。 - 執行緒安全 (Thread Safety):在多執行緒環境下,不可變的資料是安全的,不需要複雜的同步機制。
- 函數式編程精神:鼓勵使用不可變資料,減少副作用 (Side Effects)。
編譯時期常數 (const val)
如果你需要定義一個全域的、編譯時期就確定的常數,可以使用 const val。
它通常放在檔案的最上層 (Top Level) 或 Object 中。
const val PI = 3.14159
const val APP_NAME = "MyApp"
注意:val 可以是在執行時期計算出來的值 (val time = System.currentTimeMillis()),但 const val 必須在編譯時就確定 (String 或 Primitive Type)。
除非真的需要修改變數的值,否則請預設使用
val。這能讓程式碼更安全、更容易維護。var (可變變數)
var 代表 Variable。
你可以隨時修改它的值(但不能改變型別)。
var age = 18
age = 19 // 合法
// age = "20" // 錯誤!型別不符 (整數不能變字串)
型別推斷 (Type Inference)
你有注意到上面的例子沒有寫型別嗎? Kotlin 非常聰明,它會根據你給的初始值,自動推斷出變數的型別。
val name = "Miko" // 自動推斷為 String
val age = 18 // 自動推斷為 Int
如果你想顯式宣告型別,可以用冒號 : 加上型別名稱:
val name: String = "Miko"
val age: Int = 18
延遲初始化
有時候我們不想要 (或無法) 在宣告變數時馬上給初始值。這裡有兩種常見的做法:
lateinit var
有些時候我們無法在宣告時馬上給初始值 (例如在 Android 的 onCreate 中才要初始化 View)。
這時可以使用 lateinit var (Late Initialization)。
lateinit var message: String
fun init() {
message = "Hello"
}
注意:
- 只能用於
var。 - 不能用於 Primitive Types (Int, Double, Boolean...)。
- 在存取前必須確保已經初始化,否則會噴
UninitializedPropertyAccessException。
by lazy (惰性初始化)
如果你使用的是 val,並且希望在 第一次存取時 才計算初始值 (適合初始化很耗資源的物件),可以使用 by lazy。
// 只有當第一次用到 database 時,大括號內的程式碼才會執行
val database: Database by lazy {
println("Connecting to DB...")
Database.connect()
}
fun main() {
println("App Start")
// 這裡才會印出 "Connecting to DB..."
println(database.isConnected)
}
- 只能用於
val。 - 預設是 執行緒安全 (Thread Safe) 的。