Skip to content

[Kotlin] 語言基本教學筆記

Last Updated on 2021-10-21 by Clay

以下紀錄的筆記源自 Kotlin 官方文件:https://kotlinlang.org/docs/basic-syntax.html

其中我畫蛇添足地補述了一些我自己學習時搞混的觀念、以及我會寫錯的程式提醒。

希望不會太難讀。

  • 套件(package)定義與導入(import)
  • 程式進入點(program entry point)
  • 函式(functions)
  • 變數(variables)
  • 類別(classes)
  • 註解(comments)
  • 字串(string)
  • 條件式(conditional expressions)
  • 迴圈(for loop and while loop)
  • when
  • 範圍(ranges)

套件(package)定義與導入(import)

套件(package)

package org.example

fun printMessage() { /* ...  */ }
class Message { /* ...  */ }



源文件source file)中所有的內容,無論是類別class)還是函式function)都屬於聲明的套件package)。

以上方的例子來說的話:

  • printMessage() 全名應為 org.example.printMessage()
  • Message 全名應為 org.example.Message

如果沒有指定套件的話,該程式文件的內容屬於沒有名字的預設套件。


導入(import)

有許多套件會默認導入到每個 Kotlin 文件當中:

根據不同的平台,還會導入額外的套件:

而若要手動導入,則可以使用以下方法:

import org.example.Message



或者,你也可以使用 * 導入所有內容:

import org.example.*



如果導入的套件之間名字發生衝突,則可以使用 as 關鍵字重新命名來解決這個問題:

import org.example.Message
import org.test.Message as testMessage



程式進入點(program entry point)

在 Kotlin 程式當中,進入點是 main() 函式。

fun main() {
    println("Hello!")
}



函式(functions)

我們使用 fun 關鍵字來定義函式(function)。

函式的括號中可以宣告傳入的變數、括號後則可以設定回傳的資料型態。

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

fun main() {
    val a = 1
    val b = 2
    println(sum(a, b))
}


Output:

3

變數(variables)

唯讀的局部變數使用 val 關鍵字;可以重新賦值的變數則使用 var 關鍵字。

以下三種方法都可以宣告變數並賦值。

fun main() {
    // Init
    val a: Int = 1  // immediate assignment
    val b = 2       // "Int" type is inferred
    val c: Int      // Type required when no initializer is provided
    c = 3           // deferred assignment
    
    // Print
    println("a = $a")
    println("b = $b")
    println("c = $c")
}


Output:

a = 1
b = 2
c = 3


不過使用 val 並不能重新賦值,若要重新賦值,我們會需要使用 var 關鍵字。

fun main() {
    // Init
    var a = 1;
    a += 10;
    
    // Print
    println("a = $a")
}


Output:

a = 11

類別(classes)

要定義一個類別class),需要使用關鍵字 class

class Shape



而類別的屬性,則可以在類別的區塊內定義。比方說,我們可以宣告類別 Rectangle 的一個屬性:周長perimeter)。

class Rectangle(var height: Double, var length: Double) {
    var perimeter = (height + length) * 2
}



接著我們建立實例instances)並嘗試印出實例的周長屬性。

class Rectangle(var height: Double, var length: Double) {
    var perimeter = (height + length) * 2
}


fun main() {
    val r = Rectangle(4.0, 3.0)
    println("The perimeter of instance r is ${r.perimeter}")
}



Output:

The perimeter of instance r is 14.0



繼承(Inheritance)

若是類別需要繼承另外一個類別,則可以使用 : 關鍵字宣告;而要繼承的類別,則需要使用 open 關鍵字標記。

open class Shape

class Rectangle(var height: Double, var length: Double): Shape() {
    var perimeter = (height + length) * 2
}




註解(comments)

Kotlin 的註解分成單行註解single-line)以及多行註解(multi-line

// This is an end-of-line comment

/* This is a block comment
   on multiple lines. */





字串(string)

Kotlin 中的字串需要使用雙引號 "" 來設定,可以賦值給變數。若是要在字串內印出變數(variable),可以使用 "$variable" 這樣的形式印出。

也可以使用 replace() 來替換字串的內容。

fun main() {
    // Print variable in string
    var a = 1
	val s1 = "a is $a"

	// Replace the content of string
	a = 2
	val s2 = "${s1.replace("is", "was")}, but now is $a"
	
    // Print
    println("s1: $s1")
    println("s2: $s2")
}




Output:

s1: a is 1
s2: a was 1, but now is 2

條件式(conditional expressions)

if 後面會接著判斷式,若是判斷條件不符合,則繼續判斷下一個 else if 的條件 ...... 若是全部的條件都不符合,則執行 else 底下的程式碼。

fun maxOf(a: Int, b: Int) {
    if (a > b) {
        println("a > b\n")
    }
    else if (a < b) {
        println("a < b\n")
    }
    else {
        println("a = b\n")
    }
}

fun main() {
    // Init
    var a = 0
    var b = 0
    
    // Example 1
    a = 1
    b = 2
    println("Example: a=$a, b=$b")
    maxOf(a, b)

    // Example 2
    a = 2
    b = 1
    println("Example: a=$a, b=$b")
    maxOf(a, b)
    
    // Example 3
    a = 2
    b = 2
    println("Example: a=$a, b=$b")
    maxOf(a, b)
}



Output:

Example: a=1, b=2
a < b

Example: a=2, b=1
a > b

Example: a=2, b=2
a = b

迴圈(for loop and while loop)

迴圈大致上分成兩種: for-loop 以及 while-loop

for 迴圈(for loop)

Case 1

fun main() {
    for (i in 1..3) {
        println(i)
    }
}


Output:

1
2
3


Case 2

fun main() {
    for (i in 10 downTo 0 step 2) {
        println(i)
    }
}


Output:

10
8
6
4
2
0


Case 3

fun main() {
    // Init
    val arr = listOf(100, 200, 300, 400, 500)
    
    // For
    for ((index, value) in arr.withIndex()) {
        println("array index: $index, element: $value")
    }
}


Output:

array index: 0, element: 100
array index: 1, element: 200
array index: 2, element: 300
array index: 3, element: 400
array index: 4, element: 500




while 迴圈(while loop)

whiledo-while 之間的差別,在於 while 會在每一次的迴圈開始前檢查條件、而 do-while 則是在迴圈執行完後才檢查條件,故 do-while 至少會執行一次。

fun main() {
    // Init
    val arr = listOf(100, 200, 300, 400, 500)
    
    // while
    var index = 0
    while (index < arr.size) {
        println("array index: $index, element: ${arr[index]}")
        ++index
    }
}


Output:

array index: 0, element: 100
array index: 1, element: 200
array index: 2, element: 300
array index: 3, element: 400
array index: 4, element: 500



do-while

fun main() {    
    // Init
    val a = 10
    val b = 3
    
    // do-while
    do {
        println("Execute at least once anyway")
    } while (a < b)
}


Output:

Execute at least once anyway

when

when 也是一種條件判斷式,可以設定多種不同情況的分支,類似於 C 語言中的 switch

fun main() {    
    val a = 23
    when (a) {
        in 1..10 -> println("a is in the range of 1 to 10")
        in 11..20 -> println("a is in the range of 11 to 20")
        in 21..30 -> println("a is in the range of 21 to 30")
    }
}


Output:

a is in the range of 21 to 30

範圍(ranges)

其實上方的範例程式碼已經多有提及了。使用 a..b 可以設定一個 ab範圍range);而若是要判斷數值是否存在 range 之中,則使用 in 關鍵字。

fun main() { 
    val a = 4
    if (a in 0..10) {
        println("a is in the range of 0 to 10")
    }
}


Output:

a is in the range of 0 to 10


除此之外,也可以使用 in 來迭代:

fun main() { 
    for (i in 1..3) {
        println(i)
    }
}


Output:

1
2
3

References


Read More

Tags:

Leave a Reply