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 文件當中:
- kotlin.*
- kotlin.annotation.*
- kotlin.collections.*
- kotlin.comparisons.* (自 1.1 起)
- kotlin.io.*
- kotlin.ranges.*
- kotlin.sequences.*
- kotlin.text.*
根據不同的平台,還會導入額外的套件:
- JVM:
- java.lang.*
- kotlin.jvm.*
- JS:
而若要手動導入,則可以使用以下方法:
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)
while 跟 do-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
可以設定一個 a
到 b
的範圍(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
- https://kotlinlang.org/docs/basic-syntax.html
- https://developer.android.com/codelabs/basic-android-kotlin-training-kotlin-birthday-message?continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-kotlin-one%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-training-kotlin-birthday-message#0