RUST 學習日記 第20課 ——閉包
0x00 回顧與開篇
我們已經通過兩節(jié)課介紹了Rust的函數(shù)使用方法涮拗,尤其是要學會使用Rust的高階函數(shù),它在后續(xù)的項目編寫中會變得很常用善玫。這節(jié)課學習函數(shù)的另一種表現(xiàn)形式——閉包(Closure)工窍,有些人也被稱其為匿名函數(shù),但不準確壁畸。
0x01 閉包的定義
閉包(Closure)通常是指詞法閉包贼急,是一個持有外部環(huán)境變量的函數(shù)。外部環(huán)境是指閉包定義時所在的詞法作用域捏萍。外部環(huán)境變量太抓,在函數(shù)式編程范式中也被稱為自由變量,是指并不是在閉包內定義的變量令杈。將自由變量和自身綁定的函數(shù)就是閉包走敌。閉包通常有參數(shù)列表(由兩條豎線包裹)和表達式組成,語法形式如下逗噩。
| parameters | expression
示例代碼如下:
let add = |a, b| a + b;
// let add: fn(i32, i32) -> i32 = |a, b| a + b;
let result = add(1, 2);
// let result = add(1.2, 3.4);
dbg!(result);
代碼運行結果:
result = 3
解釋下上面的代碼掉丽,第一行代碼聲明了一個函數(shù)類型跌榔,其使用閉包語法創(chuàng)建的。我們沒有為其指定類型捶障,它會根據(jù)上下文推斷為fn(i32, i32) -> i32
類型僧须,相當于第二行注釋。再看第4行注釋的代碼项炼,如果將它打開則會報錯担平,因為前面已經將其推斷為fn(i32, i32) -> i32
類型,不再接收其它類型锭部。從上面的代碼來看暂论,又感覺閉包是簡化版的函數(shù)。
0x02 從函數(shù)到閉包
下面用一個例子來看下從函數(shù)到閉包經過了哪些變化拌禾。
首先我們先定義一個函數(shù)
fn add(a:i32, b:i32) -> i32 {a + b}
轉成閉包空另,使用let關鍵字聲明,括號變成管道符號蹋砚。最后添加分號結束扼菠。
let add = |a:i32, b:i32|->i32 {a + b};
簡化,去除參數(shù)類型的聲明坝咐。閉包并不像函數(shù)那樣嚴格要求注明函數(shù)類型和返回值類型循榆,去除括號。
let add = |a, b| {a + b};
繼續(xù)簡化墨坚,
let add = |a, b| a + b;
0x03 捕獲變量
在閉包中還存在一個特點秧饮,它可以捕獲和使用其被定義時所在的作用域中的變量。
示例代碼如下:
let k = 8;
let add_var = |a| a + k;
let result = add_var(10);
dbg!(result);
代碼運行結果:
result = 18
0x04 小結
本節(jié)介紹了Rust的閉包泽篮〉潦總結下閉包的特點吧。
- 閉包不嚴格要求注明參數(shù)和返回值類型
- 不注明類型的閉包帽撑,若多次調用但傳遞不同類型泼各,則會發(fā)生錯誤
- 閉包可以捕獲和使用其所在作用域中的變量
- 閉包通常適用于相對較小的場景上下文
- 閉包性能要快于函數(shù)指針(后續(xù)章節(jié)會詳細介紹)
本節(jié)課僅僅是簡單介紹了閉包的使用,關于閉包其實還有更多的知識點亏拉。在后續(xù)的Rust進階課程中我會再次講解閉包扣蜻。
0x04 本節(jié)源碼
020 · StudyRust - 碼云 - 開源中國 (gitee.com)
下節(jié)預告—— 迭代器。