1. 程式人生 > >Kotlin高階函式和Lambda表示式

Kotlin高階函式和Lambda表示式

高階函式和Lambda表示式

高階函式是接受函式作為引數或者將函式作為返回值的函式。我們可以將C語言中使用回撥函式的函式稱為高階函式。

例如我們有一個數值處理函式processNum(),對於給定Int型資料,依次執行兩個處理過程 proc1 和 proc2 :

fun processNum(num: Int, proc1: (Int) -> Int, proc2 (Int) -> Int): Int {
    return proce2(proc1(num))
}

如上,processNum()是高階函式,它包含函式型別引數proc1proc2

高階函式需要函式作為引數,這就要求呼叫時需要一個函式實參。如果在其他地方宣告函式並在高階函式呼叫處傳入非常不利於程式碼閱讀的連貫性(各種程式碼跳轉很難閱讀),並且有時函式的實現邏輯非常的簡單,重新宣告一個函式的大部分程式碼都是模板程式碼。這時Lambda表示式就有用了。

可以將Lambda理解為“字面值函式”。試想,如果在呼叫一個函式時我們已經知道了一個 Int 實參就是字面值 1 ,那麼我們就可以直接使用1作為引數呼叫這個函式而不需要宣告一個Int變數將它賦值為 1 然後再作為實參去呼叫函式! 使用Lambda表示式的思路與此類似:如果我們已經知道了這個函式引數的“樣子”我們就可以直接用Lambda表示式表示出來作為實參,而不需要再宣告一個函式並將函式作為實參!

it 語法糖

如果Lambda表示式只有一個引數那麼可以省略該引數和 -> 並可以在Lambda表示式中使用 it 來代替該引數。在Lambda的唯一引數被省略時,it 用來代表該引數!

Lambda 表示式和閉包

Lambda表示式能夠訪問其閉包中的變數,不同於Java,Kotlin還可以修改這些變數。如果 this 在閉包中有定義,那麼在Lambda表示式中也可以使用this。

Lambda表示式中的 this 需要特別注意,如果為Lambda表示式指定了 receiver 那麼在Lambda表示式中 this 代表它的 receiver,否則 this 與其閉包中的 this 等價。 如果需要訪問Lambda表示式閉包中的變數,而這個變數名和其receiver中的變數名衝突,此時需要 [email protected]<closureName>.<varNmae>

語法來指明該變數是Lambda表示式閉包中的變數。如果情況複雜分不清 this 指向誰,那麼總是使用 [email protected] 是不容易出錯的做法!

Kotlin 標準庫中的高階函式

run 函式

不帶 receiver 的 run 函式執行引數中的可執行物件,將返回值作為 run 的返回值:

/**
 * Calls the specified function [block] and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R = block()

帶 receiver 的 run 將上下文中的 this 指向 receiver 並執行引數中的可執行物件,將返回值作為 run 的返回值:

/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R = block()

with 函式

換了個寫法的帶 receiver 的 run 函式:

/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

apply 函式

類似帶 receiver 的 run 函式,可執行物件引數的執行上下文中 this 被設定為receiver。不同的是apply返回 receiver 本身。

/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }

apply 函式將處理過程“應用”到 receiver 上並返回 receiver 本身,這適用於修改 receiver 的場景,比如將某個函式的返回值修正一下。

let 函式

let 函式將 receiver 作為其可執行物件引數的實參傳入並執行可執行物件,返回值是可執行物件的返回值:

/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)

結合 it語法糖。一般來說在寫傳入 let 函式的Lambda表示式引數時往往使用 it 表示 let 的 receiver 。

also 函式

它和 let 函式的關係類似於 apply 和帶 receiver的 run 函式的關係。also 函式將 receiver 作為其可執行引數的實參傳入並執行可執行物件,但是其返回值為 receiver 本身

/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

如何選擇?

:)

Kotlin 容器類相關高階函式

相關推薦

Kotlin高階函式Lambda表示式

高階函式和Lambda表示式 高階函式是接受函式作為引數或者將函式作為返回值的函式。我們可以將C語言中使用回撥函式的函式稱為高階函式。 例如我們有一個數值處理函式processNum(),對於給定Int型資料,依次執行兩個處理過程 proc1 和 proc2

高階函式Lambda表示式

高階函式就是可以接受函式作為引數並返回一個函式的函式。 為高階函式傳遞函式型別引數值可以用如下3種方法 1. 直接定義函式,並傳遞,在函式名前需要加:: 1. 使用Lambda表示式 1. 使用

Kotlin程式設計之高階函式Lambda表示式,匿名函式

Kotlin程式設計相關知識點介紹: 高階函式 A higher-order function is a function that takes functions as parameters, or returns a function

Python中的enumerate函式lambda表示式

Python中的enumerate函式和lambda表示式 Python enumerate()函式 功能:enumerate() 函式用於將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般用在 for 迴圈當中。 語法 enumer

python學習中的reduce()函式lambda表示式

reduce()函式和lambda表示式常常能夠言簡意賅的表達我們想要的公式,但是問題也隨之而來:即表示式嚐嚐難以捉摸,看似高深莫測。這裡,我們簡單地探討一下這兩個表示式。如果後續學習中再次遇到這個問題,會繼續補充。同時,也懇請博友指教和補充,大家共同進步。       首

ASP EF框架,擴充套件函式lambda表示式實現排序分頁

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControl

python中reduce函式lambda表示式的學習

最近學習了reduce函式和lambda表示式的組合應用,十分方便,可以代替一些迴圈操作。 例如如下程式碼: list = [1,2,3,4,5] print reduce(lambda x,y:x+y,list) 其中reduce函式是python中的一個二元內建函式

《零基礎入門學習Python》(21)--函式lambda表示式(內建BIF filte()map())

前言 接下來學習怎麼建立匿名函式 知識點 lambda 表示式 Python 允許使用lambda關鍵字建立匿名函式 lambda 函式怎麼使用?  單個引數 >>> def add(x): retur

Action<T>Func<T>泛型委託,委託,泛型,匿名函式Lambda表示式的綜合使用

前言 在上篇文章C#中委託(delegate)和多播委託的理解中已經基本瞭解了委託的用法。 由於委託封裝的方法我們不一定知道其傳入的引數和返回值,例如之前說的的排序方法—————在物件的排序演算法中,需要對物件進行比較,而不同物件比較的方法不同,所以比較兩個物件的方法的引用可以作為引數傳

Kotlin學習之旅(D4)-函式Lambda表示式

Kotlin學習之旅-第四天 今天的主題是:函式與Lambda表示式 前言 函式 Kotlin裡面的函式其實在之前的學習中已經見過了,通過 fun 關鍵字來標識 fun double(x: Int): Int { return 2 * x } 預

ActionFunc泛型委託,委託,泛型,匿名函式Lambda表示式的綜合使用

前言 在上篇文章C#中委託(delegate)和多播委託的理解中已經基本瞭解了委託的用法。 由於委託封裝的方法我們不一定知道其傳入的引數和返回值,例如之前說的的排序方法—————在物件的排序演算法中,需要對物件進行比較,而不同物件比較的方法不同,所以比較兩個物件

c++ 11 陣列 lambda表示式 語法 / 函式包裝器 基本用法

//倒敘遍歷陣列並輸出  // []裡面的變數可以當做返回值來理解 (int x) 這裡就是每次迭代器的值,也就是陣列的元素的值 void main() { array<int, 5>

Kotlin學習筆記(九)函式Lambda表示式

函式 Kotlin中,使用fun關鍵字定義一個函式,函式引數使用 Pascal 表示法定義,即 name: type。引數用逗號隔開。每個引數必須有顯式型別。 fun foo(arg1:String,arg2:Boolean,arg3:Int):Int{

[.net core自我修煉2]SQL、LINQLambda表示式

隨便說說 自己想到什麼就記錄下來了,都是自己遇到的技術點,湊合看吧。在寫後端的時候,最常用的是Lambda表示式,這就記錄一下SQL、LINQ和Lambda的不同之處。 參考資料:https://blog.csdn.net/u010926964/article/details/46240

python--- map函式lambda函式

1...lambda 函式相當於一個匿名函式,顧名思義就是不用取名字的函式,相當於現實中的匿名信。 舉例: lambda x,y: x+y m = lambda x,y,z: (x-y)*z print (m(3,1,2))  執行結果:4 2...map函式&nb

第021講:函式lambda表示式

測試題 0. 請使用lambda表示式將下邊函式轉變為匿名函式? def fun_A(x, y=3): return x * y lambda x, y=3 : x * y 1. 請將下邊的匿名函式轉變為普通的屌絲函式? lambda x : x if x %

執行緒池lambda表示式

執行緒池1.什麼是執行緒池.一個用來建立和管理執行緒的容器;2.執行緒池的作用.提高執行緒的複用性,降低資源消耗提高執行緒的響應速度,提高執行緒的可管理性3.執行緒的核心思想;執行緒的複用 4.執行緒池的建立ExecutorService pools = Executors.newFixedThreadPoo

高階函式虛擬環境的配置

zip() list1 = [4,2,3,7,5] list2 = [1,2,3,4] # zip()函式裡面可以傳遞多個列表 list3 = zip(list1, list2) # 輸出[(4,1),(2,2),(3,3),(7,4)] print(list3) #

18.Java語言執行緒池Lambda表示式

執行緒等待喚醒機制 1.執行緒間的通訊:        一個程式完成某個任務,需要多個執行緒協調,就需要執行緒之間存在“通訊”,比如生產者和消費者,只有生產了才能被消費。當生產者生產完成才能告知消費者可以消費,那麼告知的過程就是執行緒間的通訊。 2.等待與喚醒機制:

匿名內部類lambda表示式

以下內容為筆者在學習過程中對相關知識點的理解和實踐的記錄,如有謬誤,還請指出。 一、匿名內部類:我看到很多人有提到“匿名內部類是沒有名字的類”,個人覺得用陳國君主編的《Java程式設計基礎(第五版)》中的 “所謂匿名內部類,是指可以利用內部類建立沒有名稱的物件,它一步完成了