iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0

第一篇有提到 Kotlin 的其中一個特點就是 Functional Programming,今天的 lambdas 也會圍繞在這個特點,在進入 lambdas 之前會先聊聊 Higher-order functions 也是構成 Functional Programming 的其中一個要點,以下如有解釋不清或是描述錯誤的地方還請大家多多指教:

什麼?

我們先來複習一下構成 Functional Programming 的幾個要點:

  • 須符合 First-Class-Object (可以像變數依樣直接賦予值也可作為其它函式的輸入參數值)
  • 高階函數 Higher-Order Functions (將函數類型作為參數或返回值)
  • 純函數 Pure Functions (相同 input 都應回傳相同 output)
  • 要避免改變資料狀態

所以在使用這個設計方法,我們會用到大量的 function types,lambda 表示式提供了特殊的語言結構,而在 Java8 開始也有 lambda 表示式,簡單來說 lambda 表示式簡化了 function 呈現的形式。

如何?

接下來會依序解釋 function types , Higher-order functions, lambdas 如何呈現:

| Function Types

Function type 以字面上的意思做解釋,就是參數類型以 function 的形式呈現,一般我們常見的類型就是 primitive type(原始型別)或是 object type(物件型別):

val a: Int = 0 // primitive type
val b: Person = Person() // object type
val onClick: () -> Unit = ... // function type

那我們來看看他的結構吧 () → Unit 左邊是輸入,右邊是輸出,還原成原本的樣子應該就會很清楚了:

fun onClick() : Unit {}

// 如果沒有命名呢? 我們稱之為匿名函數
fun () : Unit {}

如果說我們希望輸入是有值的那該怎麼寫呢?

// non-null
fun count(a: Int, b: Int) : Int {
		return a + b
}
val count: (Int, Int) -> Int = ...

// nullable
fun count(a: Int, b: Int) : Int? {
		return a + b
}
val count: ((Int, Int) -> Int)? = ...

這邊也可以透過 type alias 幫 function type 取名字,就像:

typealias ClickHandler = (Button, ClickEvent) -> Unit
val onClick: ClickHandler = ...

| Higher-order functions

將函數類型 (Function type) 作為參數或返回值,以上一篇提到的 scope function 就是一個高階函數的案例:

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

我們可以看到 apply function 裡面的參數就是 Function type。

| Lambdas

lambda 表示式跟匿名函式都是 function literals,function literals 是沒有明顯的定義與宣告以表達式的方式呈現:

// a Higher-order functions
fun View.visibleElseGone(condition: () -> Boolean) {
   visibility = if (condition()) View.VISIBLE else View.GONE
}
val a = 12
// 當我們要使用 visibleElseGone function, 參數以 lambda 表示式的方式帶入
button.visibleElseGone({ a != 0 })

// 這時候 IDE 會提示說 Lambda argument should be moved out of parentheses
button.visibleElseGone { a != 0 }

舉例一個 Kotlin 當中使用 lambda 表示式最經典的案例:

button.setOnClickListener {
     // do something
}

// 還原最初的寫法
button.setOnClickListener (object : View.OnClickListener {
     override fun onClick(p0: View?) {
           TODO("Not yet implemented")
     }
})

我們也可以看到 IDE 上的 hint 顯示的 function type:
https://ithelp.ithome.com.tw/upload/images/20220917/201511458ZnHzlBQMc.png

Reference

Official Kotlin


上一篇
Day 3.【Standard Library】Scope Functions
下一篇
Day 5.【Classes and Objects】Sealed Classes
系列文
【Kotlin Notes And JetPack】Build an App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言