基本語法概覽
這是一些基本語法元素的集合與範例。在每個章節的末尾,您會找到指向該相關主題詳細說明的連結。
您也可以透過 JetBrains Academy 提供的免費 Kotlin Core 學習路徑 來學習所有 Kotlin 的核心知識。
套件定義與匯入
套件規格應位於原始碼檔案的頂端:
package my.demo
import kotlin.text.*
// ...目錄與套件並不要求必須匹配:原始碼檔案可以任意放置在檔案系統中。
請參閱 套件。
程式入口點
Kotlin 應用程式的入口點是 main 函式:
fun main() {
println("Hello world!")
}另一種形式的 main 接受可變數量的 String 引數:
fun main(args: Array<String>) {
println(args.contentToString())
}列印至標準輸出
print 會將其引數印出至標準輸出:
fun main() {
print("Hello ")
print("world!")
}println 會印出其引數並加上換行,因此您下次印出的內容將會出現在下一行:
fun main() {
println("Hello world!")
println(42)
}從標準輸入讀取
readln() 函式從標準輸入讀取。此函式會將使用者輸入的整行內容讀取為字串。
您可以結合使用 println()、readln() 與 print() 函式來印出訊息,要求並顯示使用者輸入:
// 印出訊息以要求輸入
println("Enter any word: ")
// 讀取並儲存使用者輸入。例如:Happiness
val yourWord = readln()
// 印出帶有輸入內容的訊息
print("You entered the word: ")
print(yourWord)
// You entered the word: Happiness若要了解更多資訊,請參閱 讀取標準輸入。
函式
一個具有兩個 Int 參數且傳回型別為 Int 的函式:
fun sum(a: Int, b: Int): Int {
return a + b
}
fun main() {
print("sum of 3 and 5 is ")
println(sum(3, 5))
}函式主體可以是一個運算式。其傳回型別會被推論出來:
fun sum(a: Int, b: Int) = a + b
fun main() {
println("sum of 19 and 23 is ${sum(19, 23)}")
}不傳回任何具意義之值的函式:
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}Unit 傳回型別可以省略:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}請參閱 函式。
變數
在 Kotlin 中,您可以使用關鍵字 val 或 var 開頭來宣告變數,後跟變數名稱。
使用 val 關鍵字來宣告僅被指派一次值的變數。這些是不可變的唯讀區域變數,在初始化後不能再被指派不同的值:
fun main() {
// 宣告變數 x 並以值 5 將其初始化
val x: Int = 5
// 5
println(x)
}使用 var 關鍵字來宣告可以被重新指派的變數。這些是可變變數,您可以在初始化後更改它們的值:
fun main() {
// 宣告變數 x 並以值 5 將其初始化
var x: Int = 5
// 為變數 x 重新指派新值 6
x += 1
// 6
println(x)
}Kotlin 支援型別推論並自動識別宣告變數的資料型別。宣告變數時,您可以省略變數名稱後的型別:
fun main() {
// 宣告值為 5 的變數 x;`Int` 型別會被推論出來
val x = 5
// 5
println(x)
}您只能在初始化變數後使用它們。您可以在宣告時立即初始化變數,也可以先宣告變數後再進行初始化。在第二種情況下,您必須指定資料型別:
fun main() {
// 在宣告時初始化變數 x;不需要指定型別
val x = 5
// 宣告變數 c 但不初始化;需要指定型別
val c: Int
// 在宣告後初始化變數 c
c = 3
// 5
// 3
println(x)
println(c)
}您可以在頂層宣告變數:
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
// x = 0; PI = 3.14
// incrementX()
// x = 1; PI = 3.14
fun main() {
println("x = $x; PI = $PI")
incrementX()
println("incrementX()")
println("x = $x; PI = $PI")
}有關宣告屬性的資訊,請參閱 屬性。
建立類別與執行個體
要定義類別,請使用 class 關鍵字:
class Shape類別的屬性可以列在其宣告或主體中:
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}在類別宣告中列出參數的預設建構函式會自動可用:
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
fun main() {
val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")
}類別之間的繼承使用冒號 (:) 宣告。類別預設為 final;若要使類別可被繼承,請將其標記為 open:
open class Shape
class Rectangle(val height: Double, val length: Double): Shape() {
val perimeter = (height + length) * 2
}有關建構函式與繼承的更多資訊,請參閱 類別 以及 物件與執行個體。
註解
與大多數現代語言一樣,Kotlin 支援單行(或稱行末)註解與多行(區塊)註解:
// 這是一個行末註解
/* 這是一個多行
區塊註解。 */Kotlin 中的區塊註解可以巢狀:
/* 註解從這裡開始
/* 包含一個巢狀註解 */
並在這裡結束。 */請參閱 編寫 Kotlin 程式碼文件 以獲取有關文件註解語法的資訊。
字串範本
fun main() {
var a = 1
// 範本中的簡單名稱:
val s1 = "a is $a"
a = 2
// 範本中的任意運算式:
val s2 = "${s1.replace("is", "was")}, but now is $a"
println(s2)
}詳情請參閱 字串範本。
條件運算式
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
fun main() {
println("max of 0 and 42 is ${maxOf(0, 42)}")
}在 Kotlin 中,if 也可以作為運算式使用:
fun maxOf(a: Int, b: Int) = if (a > b) a else b
fun main() {
println("max of 0 and 42 is ${maxOf(0, 42)}")
}請參閱 if 運算式。
for 迴圈
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}或者:
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}請參閱 for 迴圈。
while 迴圈
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
}請參閱 while 迴圈。
when 運算式
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
fun main() {
println(describe(1))
println(describe("Hello"))
println(describe(1000L))
println(describe(2))
println(describe("other"))
}請參閱 when 運算式與陳述式。
範圍
使用 in 運算子檢查數字是否在某個範圍內:
fun main() {
val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}
}檢查數字是否超出範圍:
fun main() {
val list = listOf("a", "b", "c")
if (-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}
if (list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}
}反覆運算一個範圍:
fun main() {
for (x in 1..5) {
print(x)
}
}或反覆運算一個數列:
fun main() {
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
}請參閱 範圍與數列。
集合
反覆運算一個集合:
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}使用 in 運算子檢查集合是否包含某個物件:
fun main() {
val items = setOf("apple", "banana", "kiwifruit")
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
}使用 Lambda 運算式 來篩選與映射集合:
fun main() {
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.uppercase() }
.forEach { println(it) }
}請參閱 集合概覽。
可為 Null 的值與 Null 檢查
當可能出現 null 值時,參照必須明確標記為可為 null。可為 null 的型別名稱末尾帶有 ?。 例如:Int?。
如果 str 不包含整數,則傳回 null:
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}使用傳回可為 null 值的函式:
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// 使用 `x * y` 會產生錯誤,因為它們可能持有 null。
if (x != null && y != null) {
// 在 null 檢查後,x 與 y 會自動轉換為非 null 型別
println(x * y)
}
else {
println("'$arg1' or '$arg2' is not a number")
}
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}或者:
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// ...
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}
// 在 null 檢查後,x 與 y 會自動轉換為非 null 型別
println(x * y)
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("99", "b")
}請參閱 Null 安全性。
型別檢查與自動轉換
is 運算子檢查一個運算式是否為某個型別的執行個體。 如果對不可變的區域變數或屬性進行了特定型別的檢查,則不需要對其進行明確轉換:
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` 在此分支中自動轉換為 `String`
return obj.length
}
// 在型別檢查分支外,`obj` 仍為 `Any` 型別
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}或者:
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
// `obj` 在此分支中自動轉換為 `String`
return obj.length
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}甚至可以:
fun getStringLength(obj: Any): Int? {
// `obj` 在 `&&` 的右側會自動轉換為 `String`
if (obj is String && obj.length >= 0) {
return obj.length
}
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength("")
printLength(1000)
}