欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 后端 rust閉包

柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 后端 rust閉包

http://yzkb.51969.com/

一、閉包是什么

(一)閉包是什么 我們先來(lái)看看javascript中的閉包。 在函數(shù)外部無(wú)法讀取函數(shù)內(nèi)的局部變量。但是我們有時(shí)候需要得到函數(shù)內(nèi)的局部變量,那么如何從外部讀取局部變量?那就是在函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)。

function f1(){

var n=999;

function f2(){

alert(n);

}

}

在上面的代碼中,函數(shù)f2在函數(shù)f1內(nèi)部,這時(shí)f1內(nèi)部的所有局部變量,對(duì)f2都是可見(jiàn)的。但是反過(guò)來(lái)就不行,f2內(nèi)部的局部變量,對(duì)f1就是不可見(jiàn)的。這就是"鏈?zhǔn)阶饔糜?,子作用域會(huì)一級(jí)一級(jí)地向上尋找所有父作用域的變量。 既然f2可以讀取f1中的局部變量,那么只要把f2作為返回值,我們不就可以在f1外部讀取它的內(nèi)部變量了嗎!

function f1(){

var n=999;

function f2(){

alert(n);

}

return f2;

}

var result=f1();//實(shí)際上f1()執(zhí)行完之后,并沒(méi)有釋放內(nèi)存,n還在

result(); // 999。執(zhí)行f2(),能訪問(wèn)f1中的n

上一節(jié)代碼中的f2函數(shù),就是閉包。 各種專業(yè)文獻(xiàn)上的"閉包"定義非常抽象,很難看懂。我的理解是,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。 由于只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成"定義在一個(gè)函數(shù)內(nèi)部的函數(shù)"。 所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁。

閉包可以讀取函數(shù)內(nèi)部的變量,可以讓這些變量的值始終保持在內(nèi)存中。 f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制回收。

(二)閉包的優(yōu)缺點(diǎn) 優(yōu)點(diǎn): 直接訪問(wèn)父作用域中的局部變量,避免了傳參的問(wèn)題 邏輯連續(xù),避免脫離當(dāng)前邏輯,在外部編寫(xiě)代碼 缺點(diǎn): 因?yàn)槭褂瞄]包,可以使函數(shù)在執(zhí)行完后不被銷毀,保留在內(nèi)存中,如果大量使用閉包就會(huì)造成內(nèi)存泄露,內(nèi)存消耗很大

(三)使用場(chǎng)景 (1)設(shè)置timer (2)用后即棄的一次性功能,沒(méi)必要另外寫(xiě)個(gè)函數(shù)

(四)思考題 如果你能理解下面兩段代碼的運(yùn)行結(jié)果,應(yīng)該就算理解閉包的運(yùn)行機(jī)制了。 代碼片段一。

var name = "The Window";

var object = {

name : "My Object",

getNameFunc : function(){

return function(){

return this.name;

};

}

};

alert(object.getNameFunc()());

代碼片段二。

var name = "The Window";

var object = {

name : "My Object",

getNameFunc : function(){

var that = this;

return function(){

return that.name;

};

}

};

alert(object.getNameFunc()());

第一個(gè) 打印結(jié)果為T(mén)he window 第二個(gè) 打印結(jié)果為My Object this是由它所在函數(shù)調(diào)用時(shí)的環(huán)境決定的,而不是由它所在函數(shù)定義的環(huán)境決定的。 第一個(gè)this是在調(diào)用閉包時(shí)確定的,環(huán)境是全局環(huán)境 第二個(gè)this是在調(diào)用getNameFunc時(shí)確定的,環(huán)境是object內(nèi)

二、rust閉包

rust閉包,跟javascript閉包原理基本一樣。就語(yǔ)法格式不一樣。 rust閉包沒(méi)有名字,包含于一個(gè)函數(shù)內(nèi)。 所以可以直接認(rèn)為rust閉包是一個(gè)沒(méi)有函數(shù)名的內(nèi)聯(lián)函數(shù)。

(一)定義閉包 它的定義語(yǔ)法如下

|parameter| {

// 閉包的具體邏輯

}

閉包不要求在參數(shù)和返回值上注明類型 例子

|x: u32| -> u32 { x + 1 }

|x| { x + 1 }

|x| x + 1

閉包雖然沒(méi)有名稱,但我們可以將閉包賦值給一個(gè)變量

let closure_function = |parameter| {

// 閉包的具體邏輯

}

(二)使用閉包 1.使用小括號(hào) () 來(lái)調(diào)用閉包

closure_function(parameter);

范例:

fn main(){

let is_even = |x| {

x%2==0

};

let no = 13;

println!("{} is even ? {}",no, is_even(no));

}

編譯運(yùn)行結(jié)果如下

13 is even ? false

2.直接訪問(wèn)父作用域中的變量 也叫捕獲變量。閉包周圍的作用域稱為環(huán)境 不必通過(guò)傳參的方式,而是直接訪問(wèn)環(huán)境中的變量 范例:

fn main(){

let val = 10;

// 訪問(wèn)外層作用域變量val

let closure2 = |x| {

x + val // 內(nèi)聯(lián)函數(shù)訪問(wèn)外層作用域變量

};

println!("{}", closure2(2));

}

編譯運(yùn)行結(jié)果如下

12

所有的閉包都實(shí)現(xiàn)了Fn、FnMut、FnOnce特性中的一個(gè)。 閉包有三種捕獲方式,Rust會(huì)根據(jù)捕獲方式來(lái)決定它們實(shí)現(xiàn)的trait。 (1)獲取所有權(quán) 使用這種方式的閉包實(shí)現(xiàn)了FnOnce特性。 閉包獲取其所有權(quán)并在定義閉包時(shí)將其移動(dòng)進(jìn)閉包。Once代表了閉包不能多次獲取相同變量的所有權(quán),所以它只能被調(diào)用一次。

使用這種方式,要在開(kāi)頭添加move關(guān)鍵字。這種方式用于允許閉包比其捕獲的變量活得更久,例如返回閉包或生成新線程。 例子

fn main() {

let x = vec![1, 2, 3];

let equal_to_x = move |z| z == x;

println!("can't use x here: {:?}", x);

let y = vec![1, 2, 3];

assert!(equal_to_x(y));

}

x被移動(dòng)進(jìn)了閉包,因?yàn)殚]包使用move關(guān)鍵字定義。接著閉包獲取了x的所有權(quán),同時(shí)main就不再允許在println! 語(yǔ)句中使用x了。去掉println! 即可修復(fù)問(wèn)題。

(2)可變借用 使用這種方式的閉包實(shí)現(xiàn)了FnMut特性。 因?yàn)槭强勺円茫钥梢愿淖兤洵h(huán)境。

(3)不可變借用 使用這種方式的閉包實(shí)現(xiàn)了Fn特性。 因?yàn)槭遣豢勺円茫圆豢尚薷钠洵h(huán)境。

例子

fn main() {

let x = 5;

let y = 10;

// Fn閉包:通過(guò)不可變引用捕獲變量

let add = |a| a + x;

// FnMut閉包:通過(guò)可變引用捕獲變量

let mut multiply = |a| {

x * y * a

};

// FnOnce閉包:通過(guò)值捕獲變量

let divide = move |a| {

a / y

};

let result1 = add(3);

let result2 = multiply(2);

let result3 = divide(10);

println!("The results are: {}, {}, {}", result1, result2, result3);

}

復(fù)合類型(如結(jié)構(gòu)體)始終是全部捕獲的,而不是各個(gè)字段分開(kāi)捕獲的。如果真要捕獲單個(gè)字段,那可能需要先借用該字段到本地局部變量中:

struct SetVec {

set: HashSet,

vec: Vec

}

impl SetVec {

fn populate(&mut self) {

let vec = &mut self.vec;

self.set.iter().for_each(|&n| {

vec.push(n);

})

}

}

相反,如果閉包直接使用了self.vec,那么它將嘗試通過(guò)可變引用捕獲self。但是因?yàn)閟elf.set已經(jīng)被借出用來(lái)迭代了,所以代碼將無(wú)法編譯。

3.閉包作為參數(shù)和返回值 閉包可以作為函數(shù)的參數(shù)和返回值,如此使用時(shí),必須指定類型,類型就是上面講的Fn、FnMut、FnOnce。 (1)作為參數(shù)

fn f1(x: impl Fn()){

x();

}

fn f2(x:F)

where

F:Fn()

{

x();

}

fn main() {

f1(||{});

f2(||{});

}

(2)作為返回值

fn f1() -> impl Fn(i32) {

|x|{println!("{}",x)}

}

fn f2() -> impl Fn(i32) {

let a=100;

move |x|{println!("{}",x+a)} //如果使用引用方式捕獲,那么返回后a銷毀,引用會(huì)變成懸垂引用,所以編譯器不會(huì)通過(guò)

}

fn main() {

f1()(9);//9

f2()(9);//109

}

柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 后端 rust閉包

http://yzkb.51969.com/

相關(guān)閱讀

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19134459.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄