[Kotlin]學習筆記 - Functions

繼續學習 Kotin,本篇筆記會紀錄 Functions

主要特性

  1. 不需要存活在 Class 內
  2. 使用 fun 關鍵字
  3. 參數可以設定預設值
  4. 可以使用 named parameters
  5. 可以擴充既有 types

筆記

  1. Function 宣告

    1
    2
    3
    4
    fun display(message: String): Boolean {
    ....
    return true
    }
    • : String 宣告變數或回傳型別為何
  2. 支援 Expessions 型態

    1
    val message = if(a>b) "a" else "b"
  3. 如何在 Java 內呼叫 Function

    1
    2
    3
    4
    5
    6
    package com.cky
    // Util.kt 檔案
    fun display(message: String): Boolean {
    println("Hello $message")
    return true
    }

    編譯後,Java 會看成這樣,之後就跟使用其他 static function 的方法是一樣的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // class UtilKt() {
    // static boolean display(String message) { ... }
    // }

    import com.cky.UtilKt;
    public class App {
    public static void main(String[] args) {
    UtilKt.display("Hello");
    }
    }

    可以透過 @file:JvmName("SomeClassName") 的方式來改變 Jvm 看 Kotlin function 的方式

    1
    2
    3
    4
    5
    6
    7
    @file:JvmName("SomeClassName")
    package com.cky

    fun display(message: String): Boolean {
    println("Hello $message")
    return true
    }

    會轉換成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // class SomeClassName {
    // static boolean display(String message) { ... }
    // }

    import com.cky.SomeClassName;
    public class App {
    public static void main(String[] args) {
    SomeClassName.display("Hello");
    }
    }

  4. Default Parameters 在 C# 或是其他語言已經存在一段時間,但在 Java 並沒有這樣的觀念,而 Kotlin 的 Function 是可以設定預設值的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    fun display(message: String = "World"): Boolean {
    println("Hello $message")
    return true
    }

    fun main() {
    display() // 顯示 Hello world
    display("Kevin") // 顯示 Hello Kevin
    }
  5. 因為 Java 沒有 Defatul Parameters 的觀念,所以當上面的 function 要在 Java 中使用,有兩種方式,

    1. 有多少參數傳就傳多少
    2. 加上 @JvmOverloads
    1
    2
    3
    4
    5
    @JvmOverloads
    fun display(message: String = "World"): Boolean {
    println("Hello $message")
    return true
    }
  6. Named Parameters,這一個觀念在其他語言也有存在, 正常在傳參數的時候,都是依 function 設計時的順序傳,而 Named Parameters 時,就可以使用指定名稱的方式傳

    1
    2
    3
    4
    5
    6
    7
    8
    fun display(message: String = "World", logLevel: Int = 1): Boolean {
    println("Hello $message")
    return true
    }

    fun main() {
    display(logLevel = 2, message = "Kevin")
    }
    • Named Parameters 不能和 Position Parameters 混用
    • Named Parameters 順序不重要
    • Java 呼叫時,不能使用指定名稱傳值
  7. Extension Functions 的概念也存在於 C# 中,可以讓我們針對既有 Types / classes 擴充功能,例如: "abc".myCustomFunction()

    1
    2
    3
    4
    5
    6
    7
    fun String.hello(): String {
    return "Hello $this"
    }

    fun main() {
    println("Kevin".hello()) // Hello Kevin
    }
    • line2: this 表示此 extension function 所接收到的值,以此範例就是 line 6 的 "Kevin"
  8. Infix Functions

    • Member or extension function
    • Have a single parameter
    • Marked with infix keyword
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 沒有使用 infix
    fun main() {
    val h1 = Header("H1")
    val h2 = Header("H2")

    val h3 = h1.plus(h2)
    println(h3.Name) //H1H2
    }

    class Header(var Name: String) {}

    fun Header.plus(other: Header): Header {
    return Header(this.Name + other.Name)
    }

    // 使用 infix
    fun main() {
    val h1 = Header("H1")
    val h2 = Header("H2")

    val h3 = h1 plus h2 // <= 主要差異
    println(h3.Name) //H1H2
    }

    class Header(var Name: String) {}

    infix fun Header.plus(other: Header): Header {
    return Header(this.Name + other.Name)
    }
  9. 可以透過 infix 來 overloading operators (不建議大量使用)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    infix operator fun Header.plus(other: Header): Header {
    return Header(this.Name + other.Name)
    }

    fun main() {
    val h1 = Header("H1")
    val h2 = Header("H2")

    val h3 = h1 + h2 // 可以使用 + operator
    println(h3.Name) //H1H2
    }
  10. Tail Recursive Functions

    1. 使用 tailrec keyword
    2. 必須要是正確型態 (corret form)
    3. 符合上面的條件,Kotlin 就會優化 Recursive Functions

參考資料

  • Kotlin Fundamentals | Plurasight