頭條地址:https://www.ixigua.com/i677586170644791348...
B站地址:https://www.bilibili.com/video/av81202308/
1、閉包捕獲環境中的值
fn main() {
let x = 4;
let equal_to_x = |z| z == x; //捕獲環境中的值
let y = 4;
assert!(equal_to_x(y));
}
閉包可以通過三種方式捕獲其環境,它們對應函式的三種獲取引數的方式,分別是獲取所有權、可變借用、不可變借用。
這三種捕獲值的方式被編碼為如下三個Fn trait:
(1)FnOnce消費從周圍作用域捕獲的變數,閉包周圍的作用域被稱為其環境。為了消費捕獲到的變數,閉包必須獲取其所有權並在定義閉包時將其移進閉包。其名稱的Once部分代表了閉包不能多次獲取相同變數的所有權。
(2)FnMut獲取可變的借用值,所以可以改變其環境。
(3)Fn從其環境獲取不可變的借用值。
當建立一個閉包時,rust會根據其如何使用環境中的變數來推斷我們希望如何引用環境。由於所有閉包都可以被呼叫至少一次,因此所有閉包都實現了FnOnce。沒有移動被捕獲變數的所有權到閉包的閉包也實現了FnMut,而不需要對捕獲的變數進行可變訪問的閉包實現了Fn。
2、如果希望強制閉包獲取環境中變數的所有權,可以在引數列表前使用move關鍵字。例子如下:
fn main() {
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x; //移動到閉包
println!("x ===== {}", x); //此處報錯,因為x已經被移動到閉包中
let y = vec![1, 2, 3];
assert!(equal_to_x(y));
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結