Kotlin 101 學習筆記(1):變數宣告、資料型態、Function、Control Flow

Kotlin 101 學習筆記(1):變數宣告、資料型態、Function、Control Flow

最近上班開始接觸 Kotlin,雖然過去主要使用 Java,但實際寫過 Kotlin 後,能明顯感受到它在語法設計上更加簡潔!以下是我在上 LinkedIn Learning 的 Kotlin 教學影片的彙整筆記。

變數宣告

在 Kotlin 中,變數宣告主要分成兩種:

var:可重新賦值

val:不可重新賦值(類似 Java 的 final

使用 val 宣告唯讀變數

val name = "Jeremy"
val age = 25

編譯器會自動推斷型別(Type Inference)。

等同於:

val name: String = "Jeremy"
val age: Int = 25

如果嘗試修改賦值,如

val name = "Jeremy"
name = "Tom" // 錯誤

會出現編譯錯誤。


使用 var 宣告可變變數

var score = 80

score = 90

也可以明確指定型別:

var score: Int = 80

Kotlin 的特色之一是通常不需要寫型別,會自動型別推斷。


常見資料型別

整數

val age: Int = 25
val population: Long = 8000000000L

浮點數

val pi: Double = 3.14159
val height: Float = 175.5F

布林值

val isStudent: Boolean = true

字元

val grade: Char = 'A'

字串

val name: String = "Jeremy"

Raw String("""

val text = """
Hello
World
"""

String Template

val name = "Jeremy"
val age = 25

println("My name is $name")
println("I am $age years old")

Nullable 變數

var name: String? = null

? 表示這個變數可以存放 null(nullable)。

var aNullableString: String? = null

println(aNullableString!!.length)
println(aNullableString?.length)
println(aNullableString?.length ?: "The value is null")

!! 的意思是:我保證它不是 null!

相當於

(aNullableString as String).length

但由於上例的 aNullableString = null,因此會報

NullPointerException

?. 稱為 Safe Call Operator(安全呼叫運算子)

意思是如果不是 null 就執行,否則回傳 null。

?: 稱為 Elvis Operator

意思是左邊是 null 就使用右邊的值。

因此上例

println(aNullableString?.length ?: "The value is null")

的輸出結果為

The value is null

Function

Kotlin 使用 fun 關鍵字宣告函式:

fun greet(name: String) {
    println("Hello $name")
}

呼叫:

greet("Jeremy")

如果函式需要回傳值:

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

Kotlin 也支援更簡潔的寫法:

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

預設參數

Kotlin 支援預設參數,不需要像 Java 一樣寫多個 Overload。

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

呼叫:

greet()

輸出:

Hello Guest

Lambda

Lambda可以被視為是一個沒有名稱的函式。

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

如果使用 Lambda:

val add = { a: Int, b: Int ->
    a + b
}

呼叫方式一樣為:

println(add(3, 5))

Higher-Order Function

當函式能夠接收另一個函式作為參數時,就稱為 Higher-Order Function。

例如:

fun calculate(
    a: Int,
    b: Int,
    operation: (Int, Int) -> Int
): Int {
    return operation(a, b)
}

其中:

(Int, Int) -> Int

表示:

  • 接收兩個 Int
  • 回傳一個 Int
val result = calculate(3, 5) { x, y ->
    x + y
}

println(result)

輸出:

8

如果改成:

val result = calculate(3, 5) { x, y ->
    x * y
}

輸出則會變成:

15

同一個函式可以根據傳入的 Lambda 執行不同邏輯。


Control Flow

Kotlin的流程控制和Java有許多相似之處。

if Expression

最基本的條件判斷:

val score = 85

if (score >= 60) {
    println("Pass")
} else {
    println("Fail")
}

在Kotlin,if 不只是條件判斷,也是一個 Expression。

因此可以直接產生值:

val result = if (score >= 60) {
    "Pass"
} else {
    "Fail"
}

甚至可以寫得更簡潔:

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

when Expression

除了 if 之外,Kotlin 也可以使用 when 處理多重條件判斷,相當於 Java 中的 switch

when (day) {
    1 -> println("Monday")
    2 -> println("Tuesday")
    3 -> println("Wednesday")
    else -> println("Unknown")
}

與 if-else chain 相比,可讀性更高。

而且和 if 一樣,when 也能回傳值:

val dayName = when (day) {
    1 -> "Monday"
    2 -> "Tuesday"
    else -> "Unknown"
}

多個條件

when (grade) {
    'A', 'B' -> println("Excellent")
    'C' -> println("Good")
    else -> println("Need Improvement")
}

範圍判斷

when (score) {
    in 90..100 -> println("A") // 等同於 90 <= score <= 100
    in 80..89 -> println("B")
    in 70..79 -> println("C")
    else -> println("F")
}

型別判斷

when (obj) {
    is String -> println(obj.length) // 不用額外將 obj 轉成 String
    is Int -> println(obj + 1)
}

Kotlin 會自動進行 Smart Cast,因此不需要額外轉型。

for 迴圈

Kotlin 的 for 迴圈建立在 Range 的概念之上。

for (i in 0..5) {
    println(i)
}

輸出:

0
1
2
3
4
5

until

不包含終點:

for (i in 0 until 5) { // 0 <= i < 5
    println(i)
}

結果:

0
1
2
3
4

step

指定間隔:

for (i in 0..10 step 2) {
    println(i)
}

輸出:

0
2
4
6
8
10

downTo

反向迭代:

for (i in 10 downTo 1) {
    println(i)
}

遍歷集合

Kotlin 可以直接遍歷 Collection:

val names = listOf(
    "Jeremy",
    "Tom",
    "Mary"
)

for (name in names) {
    println(name)
}

while 與 do-while

與大部分程式語言相同:

var count = 0

while (count < 5) {
    println(count)
    count++
}
do {
    println(count)
    count++
} while (count < 5)

發表留言