提供您專業技能的最佳管道,IT企業主管唯一推薦

提供您專業技能的最佳管道,IT企業主管唯一推薦

2024年10月16日 星期三

Kotlin函數式程式設計

 文/張益裕 Michael Chang

Kotlin支援高階函式(higher-order function),這表示函式可以宣告為一個變數,所以函式可以宣告接收函式的參數,也可以傳回一個函式。Kotlin同時支援物件導向與函數式技術,使用物件導向的特性,設計複雜與容易擴充的應用程式架構,使用高階函式的特性,可以大幅度簡化程式設計。

在Kotlin程式設計語言,除了各種一般物件型態的變數,您還可以宣告型態為「函式」的變數。跟宣告一般的函式相同,您必須定義函式的參數與回傳值,再使用lambda提供這個函式的實作。


// 接收兩個Int參數並回傳參數合計
val summary01: (Int, Int) -> Int = { x, y -> x + y }
// 可以省略型態的宣告
val summary02 = { x: Int, y: Int -> x + y }

// 沒有參數、沒有回傳值
val hello01: () -> Unit = { println("Hello Kotlin!") }
// 可以省略型態的宣告
val hello02 = { println("Hello Kotlin!") }


println("\n===== summary01 & summary02")
println( "summary01(3, 5): ${ summary01(3, 5) }" )
println( "summary02(3, 5): ${ summary02(3, 5) }" )

println("\n===== hello01 & hello02")
hello01()


在定義Kotlin函式的時候,除了接收一般物件型態參數,也可以接收函式型態參數。根據函式的實作,函式型態參數可以使用lambda expression設定預設值,或是允許接收null參數。

// response參數為函式型態,包含兩個參數,沒有回傳值
fun request(url: String,
             response: (code: Int, reason: String) -> Unit ){
    println("request $url...")
    val code = 200
    val reason = "OK"
    response(code, reason)
}

fun main(args: Array<String>) {
    request("www.codedata.com.tw") {
        code, reason -> println("$code: $reason")
    }
}

一般的函式可以根據需求定義一個回傳值型態,回傳值可以是任何物件或基本資料型態。高階函式允許函式的回傳值為函式型態,這樣的作法可以讓應用程式的設計更加靈活。

// 客戶等級與對應的折扣
enum class Level(val discount: Double) {
    NORMAL(0.9), VIP(0.8), GOLDEN(0.7)
}

// 訂單類別,包含訂單數量
data class Order(var amount: Int)

// 計算折扣的函式,接收訂單物件參數
// 回傳計算折扣的函式,參數為訂單物件,回傳值為Double,依照訂單數量計算實際的折扣
fun getDiscount(level: Level): (Order) -> Double =
        { order ->
            val amountDiscount =
                when (order.amount) {
                    in 1..10 -> 0.1
                    in 11..20 -> 0.2
                    in 21..30 -> 0.3
                    else -> 0.4
                }
            // 在lambda expression裡面可以使用外層函式的參數level
            level.discount - amountDiscount
        }

使用函式的特性,可以簡化處理複雜折扣計算的應用:

// 取得計算折扣的函式變數
val discount = getDiscount(Level.NORMAL)
println( discount( Order(16) ) )

val discount2 = getDiscount(Level.VIP)
println( discount( Order(3) ) )

加入回傳函式的特性後,可以比物件導向設計更加靈活,提供另外一個的範例:

// 會員類別,包含名稱與編號
data class Member(val firstName: String,
                  val lastName: String,
                  val id: String)

// 會員名稱種類
enum class MemberName {FIRST, LAST, ALL}

// 會員名稱搜尋函式,接收搜尋內容與種類參數
// 回傳會員過濾條件函式,參數為會員物件,回傳值為Boolean,依照名稱種類執行判斷
fun getMemberPredicate(prefix: String,
                       pn: MemberName): (Member) -> Boolean =
    when (pn) {
        MemberName.FIRST ->
            { p: Member -> p.firstName.startsWith(prefix) }
        MemberName.LAST ->
            { p: Member -> p.lastName.startsWith(prefix) }
        MemberName.ALL ->
            { p: Member -> p.firstName.startsWith(prefix) ||
                    p.lastName.startsWith(prefix)}
    }

fun main(args: Array<String>) {
    val people = listOf(Member("Simon", "Johnson", "101"),
                        Member("Mary", "Johnson", "102"),
                        Member("Sam", "Johnson", "101"))

    println("\n===== First name starts with Si")
    val predicate01 = getMemberPredicate("Si", MemberName.FIRST)
    people.filter(predicate01).forEach { println(it) }

    println("\n===== First name or last name starts with Jo")
    val predicate02 = getMemberPredicate("Jo", MemberName.ALL)
    people.filter(predicate02).forEach { println(it) }
}



相關學習資源

Related Posts:

  • 為什麼MongoDB總是在DB-Engine排行榜前五名,也是非關聯性資料庫的首選?帶你一解MongoDB的魅力所在MongoDB是一款極受歡迎的非關聯性資料庫,我們可以從他的名字來了解,相當的有野心要做大!MongoDB名稱一開始來自於英文單字"Humongous",中文意思是"龐大"的意思,命名者一開始就想好要處理龐大的數據,故將他如此命名。但因為讀音的關係,大部分人都叫他芒果資料庫,卻忽略了命名者一開始的野… Read More
  • AutoCAD 術語初學者使用指南(一)圖片來源:AUTODESK什麼是AutoCAD?AutoCAD® 是電腦輔助設計 (CAD) 軟體,專供建築師、工程師、營造專業人員建立精確的 2D 和 3D 圖面。想開始學習使用 AutoCAD?那麼讓我們從頭開始吧!“CAD 術語初學者指南”涵蓋了幫助您入門的一些基礎知識。第一部分中,我們將探索… Read More
  • 【Animate CC與javaScript互動】Animate CC 雨滴滴落倒影波動動畫作者:李啟宏 恆逸教育訓練中心資深講師  【檢視範例】【下載範例】動畫裡最常需要的自然現象即是下雨,為了讓雨滴更寫實,因此使用雨滴元件而非一般的線段,搭配水面水紋漣漪與倒影的波動,來讓整個下雨場景更逼真! 目標動畫效果:利用影片片段元件安排大量的雨滴落下,加上以圓圈製作的水紋漣… Read More
  • 在COVID-19警戒期間如何保護自己免受駭客攻擊? 在COVID-19警戒期間,網路的便利讓大家不用出門都可以購物,在家中用手機就能訂購任何產品和服務。企業也在自動化上投入了更多資金,以適應現在的WFH(在家上班)文化,然而這些新的改變,也讓許多對於網路安全知識較欠缺罰的人暴露在風險中。 儘管大規模採用各種網路技術是很方便的,但… Read More
  • IT稽核很“無聊”?該翻轉這個錯誤認知了!CISA國際電腦稽核師認證研習班    作者: Caitlin McGaw,Candor McGaw Inc. CEO兼首席招聘官  發布日期: 2021 年 3 月 4 日我最近在一個社交媒體網站上,加入了一個由專業人士組成的職業主題討論。有人發問:什麼工作無聊?第一個… Read More

0 意見:

張貼留言