安卓語言基礎之Kotlin高階函式——Lambda表示式(二)

語言: CN / TW / HK

theme: condensed-night-purple

本文正在參加「金石計劃 . 瓜分6萬現金大獎」

前言

上一篇(安卓語言基礎之Kotlin高階函式——Lambda表示式(一) - 掘金 (juejin.cn))我們學習了Kotlin中Lambda表示式與其在集合的函式式API中的使用方法,本篇我們繼續學習,去探究Lambda程式設計在安卓Kotlin開發中的其他地方的運用方法。

正篇

除了我們上一篇所說的一些集合的函式式API,其實Kotlin中呼叫Java方法也能用函式式API,也是使用了Lambda表示式,下面我們就來看看它們的用法。

Java函式式API的使用

在Kotlin中呼叫Java方法使用函式式API是有限制的,具體來說就是如果呼叫Java方法且該方法接受一個Java單抽象方法介面(指介面中只有一個待實現方法)引數,就能使用函式式API,如果遇到介面中有多個待實現方法就沒法使用函式式API,Kotlin中使用Java函式式API的Demo(使用Runnable介面)如下: Kotlin val thread = Thread(Runnable { println("Thread is running") }).start() 當然,根據上一篇,我們還能再簡化,因為當Lambda表示式為方法最後一個引數時,可以將Lambda表示式移動到方法括號外面,而如果Lambda表示式為方法唯一引數,也能將方法括號去除:

image.png val thread = Thread { println("Thread is running") }.start() 還有我們之前文章中說到的點選事件監聽,Kotlin也更加簡短: binding.saveButton.setOnClickListener { //write code } 以上就是Java函式式API的使用,十分的簡單,但Java函式式API的使用都限於從Kotlin中呼叫Java方法且單抽象方法介面也必須是用Java語言定義的,因為Kotlin中有專門的高階函式來實現更厲害的自定義函式式API功能,不需要像Java那樣藉助單抽象方法介面來實現,下面我們就來看看標準函式的用法。

標準函式

這裡的標準函式指的是Standard.kt檔案中定義的函式,因為涉及到Lambda表示式,所以在此介紹其中幾個常用的方法

with函式

有兩個引數,第一個引數是任意型別的物件,第二個引數則為一個Lambda表示式。 with函式將第一個引數作為Lambda表示式中物件的上下文,並使用Lambda表示式中最後一行程式碼作為返回值返回,如下: Kotlin val result = with(binding) { //dialogHeight物件的上下文 "value"//with函式的返回值 }

應用Demo

比方說我們有個水果的列表,然後開始吃,吃完所有水果,我們依次打印出來 原本寫法: Kotlin val lists = listOf("Apple", "Pear") val builders = StringBuilder() builders.append("eating.\n") for (fruit in lists) { builders.append(fruit).append("\n") } builders.append("All fruits.") val res = builders.toString() println(res) 但使用with,我們可以更簡單的表示: ```Kotlin val list = listOf("Apple", "Pear", "Banana")

val result = with(StringBuilder()) { for (fruit in list) { append(fruit).append("\n") } append("All fruits.") toString() } println(result) ```

image.png 使用with函式後我們就不用一直使用物件去呼叫方法,重複去寫物件名,而是直接在with函式中傳物件引數後的Lambda表示式中直接呼叫其方法,最後一句作為返回即可。

run函式

與with函式相似,但不是直接呼叫而是在物件上呼叫,且只接受Lambda表示式這一個引數: ```Kotlin val listR = listOf("Apple", "Pear", "Banana")

val resultR = StringBuilder().run { for (fruit in listR) { append(fruit).append("\n") } append("All fruits.") toString() } println(resultR) ``` 與上面with列印結果是一樣的:

image.png

apply函式

該函式結構體和上面的run函式類似,但返回結果不同,apply函式返回的不是Lambda表示式最後一句而是呼叫方法的物件本身,所以我們程式碼也隨之變化: ```Kotlin val listA = listOf("Apple", "Pear", "Banana")

val resultA = StringBuilder().apply { for (fruit in listA) { append(fruit).append("\n") } append("All fruits.") } println(resultA.toString()) 介紹完這幾種函式,其實它們之間很明顯都可以相互轉換,只是用法上的區別要注意好,此外,這些方法通常用於在重複寫物件名呼叫方法時用到,可以寫出更簡潔的程式碼,比如使用intent傳參跳轉: 原本寫法:Kotlin val intent = Intent(this, WebViewTest::class.java) intent.putExtra("param1", "data1") intent.putExtra("param2", "data2") intent.putExtra("param3", "data3") this.startActivity(intent) 使用apply函式後Kotlin val intents = Intent(this, WebViewTest::class.java).apply { putExtra("param1", "data1") putExtra("param2", "data2") putExtra("param3", "data3") } this.startActivity(intents) ``` 簡化一些,而且傳的引數越多越明顯。

總結

本篇終於把關於Lambda表示式有關的內容前置說完了,下一篇正式開始使用高階函式,感謝大家觀看。