Kotlin系列之Lambda表达式(1)
今天開始后續的幾篇Kotlin的文章會介紹Kotlin中Lambda表達式相關的內容。
什么是Lambda表達式
在Java8中引入了Lambda表達式,這是最令Java開發者激動和期待的一個功能。那究竟什么是Lambda表達式呢?
Lambda表達式本質上是可以傳遞給其他函數的一小段代碼,我們在之前的Java或者Kotlin中,一個函數的參數可以是一種簡單的基本數據類型變量或一個對象實例變量。Lambda表達式的出現可以讓我們可以把一段代碼當做一個值來進行對待,由于是值,便可以進行傳遞,所以Lambda可以被當做參數傳遞給其他函數。Lambda表達式的出現,讓我們的代碼更加簡潔。
Kotlin中的Lambda表達式
上面的文字描述可能比較抽象,我們舉一個實際的例子。我們定義一個數據類人(對于Kotlin數據類不了解的可以查看這篇文章Kotlin系列之數據類和類委托)。我們的目的是找出一堆人中年齡最大的那個人。
我們先用最基礎的Kotlin知識來解決上述問題。代碼示例如下:
data class People(val name: String, val age: Int)fun findTheOldest(peopleList: List<People>) {var maxAge = 0var theOldestPeople: People? = nullfor (people in peopleList) {if (people.age > maxAge) {maxAge = people.agetheOldestPeople = people}}println(theOldestPeople) }fun main(args: Array<String>) {val peopleList = listOf<People>(People("小白", 22),People("小紅", 23), People("琦琦", 20))findTheOldest(peopleList) } 復制代碼但是Kotlin中可以使用庫函數配合Lambda將代碼進行大大的簡化,我們先看看可以最終可以簡化到何種程度。代碼如下:
fun main(args: Array<String>) {val peopleList = listOf<People>(People("小白", 22),People("小紅", 23), People("琦琦", 20))//關鍵代碼就這一行println(peopleList.maxBy { it.age }) } 復制代碼是不是被驚艷到了,代碼量大大大大減少了,而且代碼所表達的功能也更加清楚了。下面我們就來看看上面的那么多代碼是怎么利用Lambda表達式變成一行代碼的。
Lambda表達式的簡化過程
下面就來看看具體的演變過程。 首先maxBy這個函數式類似于一個比較器,它不關心具體的集合中的元素是什么類型,只需要我們傳入比較的規則即可,我們上面比較的規則是人們的年齡。所以我們可以把比較規則使用Lambda來書寫傳入maxBy函數中。
首先先讓我們看看Lambda表達式的語法。一個Lambda表達式的基本結構是這樣:
{參數1: 類型, 參數2: 類型, [...] -> 函數體} 復制代碼可以看出,一個Lambda表達式被一個花括號包圍,參數并沒有是喲圓括號括起來,參數列表和函數體之間使用箭頭進行分隔。
所以我們依據上面的格式要求,會寫出下面這樣的代碼:
peopleList.maxBy({p: People -> p.age}) 復制代碼上面是最原始的Lambda表達式代碼。
根據Kotlin的語法約定: 如果Lambda表達式是函數調用的最后一個實參,它可以放在括號的外面。 由于在這個例子中Lambda表達式是maxBy函數的唯一實參,也自然是最后一個實參,所以代碼就變成下面這樣。
peopleList.maxBy(){p: People -> p.age} 復制代碼但是要記住,當函數有多個實參時,我們既可以將Lambda表達式留在括號內,也可以放在括號的外面,但當我們傳遞的是兩個或更多個Lambda表達式時,不能把超過一個的Lambda表達式放在括號外面。
根據Kotlin的語法約定: 如果Lambda表達式是函數的唯一實參,可以去掉空的圓括號對。 所以上面的代碼又會進一步變為下面這樣。
peopleList.maxBy{p: People -> p.age} 復制代碼根據Kotlin的語法約定: 如果Lambda表達式中參數的類型可以被推導出來,那么類型聲明可以被省略。 這個例子中編譯器知道maxBy要處理的每一個元素都是People類型,所以這里不需要顯式指定類型。 所以代碼被進一步簡化為下面這樣。
peopleList.maxBy{p -> p.age} 復制代碼當然我們前面也說了,Lambda就是一段代碼,我們可以使用變量存儲它,便于多次使用。當我們使用變量存儲Lambda表達式時,由于缺少上下文環境,所以無法進行參數類型推斷,所以必須顯式指定參數類型。
根據Kotlin的語法約定: 如果Lambda表達式中只有一個參數,并且這個參數的類型可以被推斷出來,那么可以使用默認參數名稱it來代替命名參數。 所以最終代碼變成了這樣。
peopleList.maxBy{it.age} 復制代碼it雖然可縮短代碼,但是卻不可以濫用,在Lambda表達式嵌套的情況下,it沒法清楚表示到底引用的是哪個值,會造成代碼的混亂,所以在這種情況下建議顯式指定參數名稱。
最后再補充一個小點,Lambda表達式并沒有限定是單個表達式,他截圖包含更多的語句,當包含更多的語句時,最后一個表達式就是Lambda表達式的結果,就像下面這樣:
fun main(args: Array<String>) {val sum = {x: Int, y: Int ->println("start to calc...")x + y}println(sum(1, 2)) } 復制代碼寫在最后
通過上面的介紹,是不是已經被Kotlin中的Lambda表達式吸引了呢,后續還有幾篇文章將介紹Kotlin中Lambda表達式的更多內容。
歡迎關注我的微信公眾號,不定期更新Kotlin相關內容。
總結
以上是生活随笔為你收集整理的Kotlin系列之Lambda表达式(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ADC分类及参数
- 下一篇: adb shell 命令详解,andro