程式設計人員 Kotlin 新手上路課程:函式

本程式碼研究室是程式設計課程 Kotlin 新手上路課程的一部分。使用程式碼研究室逐步完成程式碼課程後,您將能充分發揮本課程的潛能。視您的知識而定,您或許可以略過某些部分。本課程的適用對象為熟悉物件導向語言,且想要學習 Kotlin 的程式設計人員。

簡介

在這個程式碼研究室,您可以建立 Kotlin 程式並瞭解 Kotlin 中的函式,包括參數、篩選器、lambda 和精簡函式的預設值。

本課程並非只建立一個範例應用程式,而是用來建立您的知識,但彼此之間互不相關,因此您可以熟悉自己熟悉的部分。許多產品是透過水族箱主題進行連結。如果您想看完整的水族箱故事,請參考程式設計程式 Kotlin 新手上路課程

須知事項

  • 現代化的物件導向靜態程式設計語言,提供基本知識
  • 如何使用至少一種語言來設計課程、方法和例外處理方式
  • 如何在 IntelliJ IDEA 中使用 Kotlin's REPL (Read-Eval-Print Loop)
  • Kotlin 基本概念,包括類型、運算子和迴圈

本程式碼研究室的適用對象為熟悉物件導向語言並想深入瞭解 Kotlin 的程式設計人員。

課程內容

  • 如何在 IntelliJ IDEA 中建立包含 main() 函式與引數的程式
  • 如何使用預設值和精簡函式
  • 如何套用名單篩選器
  • 如何建立基本的 lambda 和順序較高的函式

執行步驟

  • 使用 REPL 以嘗試一些程式碼。
  • 使用 IntelliJ IDEA 建立基本的 Kotlin 程式。

在這項工作中,您會建立 Kotlin 程式並瞭解 main() 函式,以及如何透過指令列將引數傳送至程式。

您可能會記得先前在先前的程式碼研究室中輸入 REPL 的 printHello() 函式:

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

您可以先使用 fun 關鍵字定義函式,然後再加上函式名稱。和其他程式設計語言一樣,括號 () 代表函式引數 (如果有的話)。大括號使用 {} 函式來編寫函式的程式碼。這個函式沒有任何傳回類型,因為這個函式並未傳回任何資料。

步驟 1:建立 Kotlin 檔案

  1. 開啟 IntelliJ IDEA。
  2. IntelliJ IDEA 左側的 [Project] (專案) 窗格會顯示您的專案檔案和資料夾清單。在「Hello Kotlin」底下,對 src 資料夾按一下滑鼠右鍵。(您應該已經在先前的程式碼研究室中取得 Hello Kotlin 專案)。
  3. 選取 [New > Kotlin File / Class]
  4. 將「Kind」(種類) 保留為 [File] (檔案),並將檔案命名為 Hello
  5. 按一下「OK」(確定)

src 資料夾中已經有一個名稱為 Hello.kt 的檔案。

步驟 2:加入程式碼並執行程式

  1. 如同其他程式語言,Kotlin main() 函式會指定執行作業的進入點。所有指令列引數會以字串陣列的形式傳送。

    請將下列程式碼貼到 Hello.kt 檔案中:
fun main(args: Array<String>) {
    println("Hello, world!")
}

和先前的 printHello() 函式一樣,此函式沒有 return 陳述式。即使沒有明確指定 Kotlin,所有函式都會傳回部分內容。因此,像此 main() 函式一樣的函式會傳回 kotlin.Unit 類型,這是 Kotlin 的一種,沒有任何值。

  1. 如要執行程式,請按一下 main() 函式左側的綠色三角形。從選單中選取 [Run 'HelloKt']
  2. IntelliJ IDEA 編譯並執行程式。搜尋結果會顯示在底部的記錄窗格中,如下所示。

步驟 3:將引數傳送至 main()

由於您是透過 IntelliJ IDEA 執行程式,而非透過指令列執行程式,因此必須指定一些不同的程式引數。

  1. 選取 [Run > Edit Configurations]。「Run/Debug Configurations」視窗會隨即開啟。
  2. 在「Program 改用」欄位中輸入 Kotlin!
  3. 按一下「OK」(確定)

步驟 4:將程式碼改為使用字串範本

字串範本會在字串中插入變數或運算式,而 $ 則代表該字串的一部分為變數或運算式。請大括號 ({}) 加上運算式 (如果有的話)。

  1. Hello.kt 中,將問候語改為使用傳送至 args[0] 的第一個引數,而不是 "world"
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. 執行程式,而輸出結果包含您指定的引數。
⇒ Hello, Kotlin!

在這項工作中,您會瞭解為什麼 Kotlin 中幾乎所有項目都有一個值,以及為什麼該功能很實用。

有些語言則包含陳述式,而這一行程式碼沒有值。在 Kotlin 中,幾乎所有作業都是運算式,而且具有一個值 (即使該值為 kotlin.Unit)。

  1. Hello.kt 中,在 main() 中編寫程式碼,將 println() 指派給名為 isUnit 的變數並加以列印。(println() 不會傳回值,因此會傳回 kotlin.Unit)。
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. 執行程式。第一個 println() 會列印字串 "This is an expression"。第二個 println() 會列印第一個 println() 陳述式的值,也就是 kotlin.Unit
⇒ This is an expression
kotlin.Unit
  1. 宣告名為 temperatureval 並初始化為 10。
  2. 宣告另一個val稱為isHot,分配if/else陳述式的返回值isHot,如以下代碼所示。因為這是運算式,因此您可以使用 if 運算式的值。
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. 使用字串範本中的運算式值。加入一些程式碼來檢查溫度,判斷魚是否安全或過熱,然後執行您的計劃。
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

在這項工作中,您可以進一步瞭解 Kotlin 中的函式,並進一步瞭解非常實用的 when 條件運算式。

步驟 1:建立函式

在這個步驟中,您必須彙整自己學到的部分內容,並建立不同類型的函式。您可以將 Hello.kt 的內容替換成新程式碼。

  1. 編寫名為 feedTheFish() 的函式,呼叫 randomDay() 以取得一週的隨機日。使用字串範本列印food,讓魚類當天可以吃。現在,魚每天每天都吃相同的食物。
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. 撰寫 randomDay() 函式,從陣列挑選隨機日期並傳回。

nextInt() 函式會採用整數限制,將數字從 Random() 限制為 0 到 6,以符合 week 陣列。

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Random()nextInt() 函式是在 java.util.* 中定義。在檔案頂端新增所需的匯入項目:
import java.util.*    // required import
  1. 執行您的程式並檢查輸出結果。
⇒ Today is Tuesday and the fish eat pellets

步驟 2:使用 time 運算式

再延長時間,使用 when 運算式更改程式碼,為不同的日子挑選不同的食物。其他程式設計語言中的 when 陳述式與 switch 類似,但 when 會自動在每個分支的結尾。另外,這個程式碼也可確保程式碼涵蓋所有分支版本。

  1. Hello.kt 中,新增名為 fishFood() 的函式,將一天視為 String,並以 String 傳回當天的魚類食物。使用 when(),這樣每天的魚都會得到一份特定食物。執行程式數次,以查看不同的輸出結果。
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. 使用 elsewhen 運算式新增預設分支版本。為了進行測試,為了確保您程式中的預設時間可以套用預設值,請移除 TuesdaySaturday 分支版本。

    使用預設分支版本可確保 food 在傳回結果前先取得值,因此不用再初始化。由於程式碼現在只將字串指派給 food,因此您可以使用 val 宣告 food,而不是 var
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. 每個運算式都有一個值,因此這個程式碼可能更精簡。直接傳回 when 運算式的值,並刪除 food 變數。when 運算式的值是滿足條件的最後一個分支版本的值。
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

您的程式最終版本看起來像這樣。

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

在這項工作中,您將瞭解函式和方法的預設值。此外,您也可以進一步瞭解精簡函式,藉此讓程式碼更簡潔且易於閱讀,並減少要測試的程式碼路徑數量。密集函式亦稱為「單一運算式函式」

步驟 1:為參數建立預設值

在 Kotlin 中,您可以透過參數名稱來傳送引數。您也可以指定參數的預設值:如果呼叫者未提供引數,系統就會採用預設值。之後當您編寫方法 (成員函式) 時,您就無需編寫許多相同方法的超載版本。

  1. Hello.kt 中,撰寫 swim() 函式,其中包含 String 參數,以列印魚類的 # 速度。speed 參數的預設值是 "fast"
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. main() 函式呼叫 swim() 函式的三種方法。首先,請使用預設值呼叫函式。接著,請呼叫函式並傳遞 speed 參數做為名稱,然後呼叫 speed 參數來呼叫函式。
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

步驟 2:新增必要參數

如果未指定參數的預設值,則一律必須傳送對應的引數。

  1. Hello.kt 中,撰寫 shouldChangeWater() 函式來接收三個參數:daytemperaturedirty 層級。如果需要修改水位,星期四就會傳回 true;如果是星期日、溫度過高或水分過多,該函式就會傳回。星期幾為必要值,但預設溫度為 22,預設負荷度為 20。

    請使用不含引數的 when 運算式,這類函式在 Kotlin 中會做為一系列的 if/else if 檢查。
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. 請撥打 feedTheFish() 與「shouldChangeWater()」聯絡,並提供該日期。day 參數沒有預設值,您必須指定引數。shouldChangeWater() 的另外兩個參數使用預設值,因此您不需要傳送引數。
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

步驟 3:建立精簡函式

您在前述步驟中撰寫的 when 運算式,會將大量邏輯封裝成少量的程式碼。如果想要稍微打包但是 Kotlin 的方法是使用精簡函式。

精簡函式 (或一個單一運算式函式) 是 Kotlin 中的常見模式。如果函式傳回單一運算式的結果,您可以在 = 符號後方指定函式的主體,並省略大括號 {},並省略 return

  1. Hello.kt 中新增壓縮函式來測試條件。
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. 變更 shouldChangeWater() 以呼叫新函式。
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. 執行程式。println()shouldChangeWater() 輸出結果,應該會和您切換到使用精簡函式時的相同。

預設值

參數的預設值不一定要是值。它可以是另一個函式,如下列部分範例所示:

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

在這項工作中,您將稍微瞭解 Kotlin 中的篩選器。篩選器可讓您根據一些條件,輕鬆取得部分名單。

步驟 1:建立篩選器

  1. Hello.kt 中,使用 listOf() 定義頂層的水族箱裝飾清單。您可以取代 Hello.kt 的內容。
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. 建立新的 main() 函式,並在當中列印出開頭為「'p'」開頭的裝飾品。篩選器條件的程式碼使用大括號 ({}),it 代表每個項目在篩選器循環播放時稱為「大括號」。如果運算式傳回 true,就會包含該項目。
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. 執行程式,您會在「Run」(執行) 視窗中看到下列輸出內容:
⇒ [pagoda, plastic plant]

步驟 2:比較 Eager 和延遲延遲篩選器

如果您熟悉其他語言的篩選器,可能會想知道 Kotlin 中的篩選器是「積極」或「延遲」。結果清單是立即建立,還是存取清單?在 Kotlin 中,您可以透過任何方式進行所需的操作。根據預設,filter 是 Eager,而每次使用篩選器時,系統都會建立清單。

如要縮短篩選器的執行時間,您可以使用 Sequence,這個集合一次只能查看一個項目,包括開頭和結尾。簡單來說,就是延遲篩選器所需的 API。

  1. Hello.kt 中,變更程式碼,將篩選後的清單指派給名為 eager 的變數,然後進行列印。
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. 在該程式碼下方,使用 Sequence 搭配 asSequence() 評估篩選器。將序列指派給名為 filtered 的變數,然後進行列印。
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

當您將篩選器結果傳回為 Sequence 時,filtered 變數不會存放新清單,而會保有 Sequence 清單元素元素以及篩選器的知識,以套用這些元素。每當您存取 Sequence 中的元素時,系統就會套用篩選器並傳回結果。

  1. 將序列轉換為具有 toList()List,強制評估序列。列印結果。
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. 執行程式並觀察輸出結果。
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

如要使用 Sequence 和延遲評估功能呈現視覺化內容,請使用 map() 函式。map() 函式會針對序列中的每個元素執行簡單的轉換。

  1. 使用與上述相同的 decorations 清單時,使用 map() 執行沒有任何轉換的轉換作業,然後只傳回傳送的元素。新增 println(),以便在每次存取元素時顯示,並將序列指派給名為 lazyMap 的變數。
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. 列印 lazyMap,使用 first() 列印 lazyMap 的第一個元素,並列印 lazyMap 轉換成 List
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. 執行程式並觀察輸出內容。列印 lazyMap 只列印 Sequence 的參照 - 內部呼叫 println() 並未呼叫。列印第一個元素只會存取第一個元素。將 Sequence 轉換為 List 會存取所有元素。
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. 套用 map 前,請使用原始篩選器建立新的 Sequence。列印結果。
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. 執行程式並觀察其他輸出內容。如同取得第一個元素,系統只對存取的元素呼叫內部 println()
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

在這項工作中,您將介紹 Kotlin 中的 lambda 和更高順序函式

Lambdas

除了傳統的已命名函式以外,Kotlin 也支援 lambdas。lambda 是用來建立函式的運算式。但您必須宣告沒有名稱的函式,而不是宣告已命名的函式。使用 lambda 運算式可以作為資料傳送,其中一個有用的方式。其他語言的 lambda 稱為匿名函式函式常值或類似名稱。

高階函式

您只要將 lambda 傳遞至另一個函式,就能建立順序較高的函式。在先前的工作中,您建立了一個名為 filter 的較高順序函式。您已將下列 lambda 運算式傳送給 filter,做為檢查條件:
{it[0] == 'p'}

同樣地,map 是順序更高的函式,您傳遞至該 lambda 則是要套用的轉換。

步驟 1:瞭解 lambdas

  1. lambdas 與已命名函式一樣具有參數。針對 lambdas,參數 (及其類型,如有必要) 會在函式函式 -> 的左側顯示。要執行的程式碼位於函式箭頭的右側。將 lambda 指派給變數後,您就可以將其呼叫為函式。

    使用 REPL ([工具] > [Kotlin > Kotlin REPL]),試用這個程式碼:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

在這個範例中,lambda 會使用名為 dirtyInt,並傳回 dirty / 2。(因為篩選功能會移除泥土。)

  1. Kotlin 的函式類型語法與 lambdas 的語法密切相關。請使用這個語法明確宣告含有函式的變數:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

程式碼的內容如下:

  • 建立名為「waterFilter」的變數。
  • waterFilter 可以是任何採用 Int 並傳回 Int 的函式。
  • 將 lambda 指派給 waterFilter
  • lambda 會傳回引數 dirty 除以 2 的值。

請注意,您再也不需要指定 lambda 引數的類型,類型是由類型推論計算得出。

步驟 2:建立順序較高的函式

截至目前為止,lambda 的範例看起來很像功能。lambdas 真正的功用是利用這些技術建立高階函式,其中某個函式的引數是另一個函式。

  1. 編寫更高的順序函式。這裡是基本範例,這個函式接收兩個引數。第一個引數是整數。第二個引數是一個需要整數並傳回整數的函式。在 REPL 中試用。
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

程式碼的主體會呼叫做為第二個引數傳送的函式,並傳遞第一個引數。

  1. 如要呼叫此函式,請傳送整數和函式。
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

您傳遞的函式不一定要是 lambda,也可以是一般命名函式。如要指定引數為一般函式,請使用 :: 運算子。這樣一來,Kotlin 就會得知您將函式參照做為引數傳送,而不是嘗試呼叫函式。

  1. 請將一般已命名函式傳送至 updateDirty()
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • 如要在 IntelliJ IDEA 中建立 Kotlin 來源檔案,請先建立 Kotlin 專案。
  • 如要在 IntelliJ IDEA 中編譯及執行程式,請按一下 main() 函式旁邊的綠色三角形。輸出結果會顯示在下方的記錄視窗中。
  • 在 IntelliJ IDEA 中,指定要在 Run > Edit Configurations 中傳送到 main() 函式的指令列引數。
  • 在 Kotlin 中,幾乎所有的值都有一個值。您可以使用這項技巧,將 ifwhen 的值做為運算式或傳回值,讓程式碼更加簡潔。
  • 預設引數會移除多個函式或方法的版本。例如:
    fun swim(speed: String = "fast") { ... }
  • 精簡函式 (或單一運算式函式) 可讓您的程式碼更清晰易讀。例如:
    fun isTooHot(temperature: Int) = temperature > 30
  • 您已經瞭解使用 lambda 運算式的篩選器相關基本知識。例如:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • lambda 運算式是用來建立未命名函式的運算式。大括號在 {} 大括號之間有定義。
  • 高順序函式中,您將 lambda 運算式等函式傳送至另一個函式。例如:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

這堂課的內容很多,特別是對新手,之後的課程會再次介紹 lambda 和更高順序的功能。

Kotlin 說明文件

如果想瞭解本課程的任一主題,或您的困難,建議您選擇 https://kotlinlang.org

Kotlin 教學課程

https://try.kotlinlang.org 網站包含稱為 Kotlin Koans 的豐富的教學課程、網頁式解譯器,以及包含參考範例的完整參考文件。

Udacity 課程

如要查看這個主題的 Udacity 課程,請參閱程式設計人員 Kotlin 新手上路課程

IntelliJ IDEA

如需 IntelliJ IDEA 說明文件,請前往 JetBrains 網站。

這個部分會列出在代碼研究室中,受老師主導的課程作業的可能學生作業。由老師自行決定要執行下列動作:

  • 視需要指派家庭作業。
  • 告知學生如何提交家庭作業。
  • 批改家庭作業。

老師可視需要使用這些建議,並視情況指派其他合適的家庭作業。

如果您是自行操作本程式碼研究室,歡迎透過這些家庭作業來測試自己的知識。

回答這些問題

第 1 題

如果字串 element 包含在字串中,contains(element: String) 函式會傳回 true。以下程式碼會輸出何種內容?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

第 2 題

以下函式定義中,何者是必要參數的?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

第 3 題

您可以將一般命名函式 (而非呼叫此結果) 傳遞至其他函式。您要如何把increaseDirty( start: Int ) = start + 1傳給updateDirty(dirty: Int, operation: (Int) -> Int)

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

繼續下一堂課:4. 類別和物件

如需課程簡介,包括其他程式碼研究室的連結,請參閱程式設計人員 Kotlin 新手課程:歡迎參加這堂課程。