安卓語言基礎之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表達式有關的內容前置説完了,下一篇正式開始使用高階函數,感謝大家觀看。