0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Rust語(yǔ)言中閉包的應(yīng)用場(chǎng)景

科技綠洲 ? 來(lái)源:TinyZ ? 作者:TinyZ ? 2023-09-20 11:25 ? 次閱讀

Rust語(yǔ)言的閉包是一種可以捕獲外部變量并在需要時(shí)執(zhí)行的匿名函數(shù)。閉包在Rust中是一等公民,它們可以像其他變量一樣傳遞、存儲(chǔ)和使用。閉包可以捕獲其定義范圍內(nèi)的變量,并在必要時(shí)訪問(wèn)它們。這使得閉包在許多場(chǎng)景下非常有用,例如迭代器、異步編程和并發(fā)編程。

閉包與函數(shù)的區(qū)別在于,閉包可以捕獲它所定義的環(huán)境中的變量。這意味著,當(dāng)閉包中使用變量時(shí),它可以訪問(wèn)該變量的值。在Rust中,閉包被設(shè)計(jì)為可以自動(dòng)推斷變量的類型,因此可以方便地使用。

Rust閉包概念和python中Lambda表達(dá)式,Java的Lambda表達(dá)式很類似,可以幫助理解和應(yīng)用。

閉包的應(yīng)用場(chǎng)景

閉包在Rust語(yǔ)言中被廣泛應(yīng)于許多場(chǎng)景。例如,在多線程編程中,閉包可以用來(lái)定義線程任務(wù)。在Web開(kāi)發(fā)中,閉包可以用來(lái)定義路由處理函數(shù)。在數(shù)據(jù)處理領(lǐng)域,閉包可以用來(lái)定義數(shù)據(jù)轉(zhuǎn)換和過(guò)濾函數(shù)等等。 下面,我們以Animal為例,演示如何使用閉包實(shí)現(xiàn)一些常見(jiàn)的數(shù)據(jù)處理和轉(zhuǎn)換操作。

use std::collections::HashMap;

#[derive(Debug)]
struct Animal {
    name: String,
    species: String,
    age: i32,
}


impl Animal {
    fn new(name: &str, species: &str, age: i32) - > Self {
        Animal {
            name: name.to_owned(),
            species: species.to_owned(),
            age,
        }
    }
}

impl Display for Animal {
    fn fmt(&self, f: &mut Formatter) - > Result {
        write!(f, "Animal info name {}, species:{}, age:{}", self.name, self.species, self.age)
    }
}

fn main() {
    let animals = vec![
        Animal::new("Tom", "Cat", 2),
        Animal::new("Jerry", "Mouse", 1),
        Animal::new("Spike", "Dog", 3),
    ];

    // 計(jì)算所有動(dòng)物的平均年齡
    let total_age = animals.iter().map(|a| a.age).sum::< i32 >();
    let average_age = total_age as f32 / animals.len() as f32;
    println!("Average age: {:.2}", average_age);

    // 統(tǒng)計(jì)每個(gè)物種的數(shù)量
    let mut species_count = HashMap::new();
    for animal in &animals {
        let count = species_count.entry(animal.species.clone()).or_insert(0);
        *count += 1;
    }
    println!("Species count: {:?}", species_count);

    // 找出所有年齡大于2歲的動(dòng)物
    let old_animals: Vec< _ > = animals.iter().filter(|a| a.age > 2).collect();
    println!("Old animals: {:?}", old_animals);

    // 將所有動(dòng)物的名字轉(zhuǎn)換成大寫
    let upper_names: Vec< _ > = animals.iter().map(|a| a.name.to_uppercase()).collect(); 
    println!("Upper case names {:?}", upper_names);
}
//    輸出結(jié)果:
// Average age: 2.00
// Species count: {"Dog": 1, "Cat": 1, "Mouse": 1}
// Old animals: [Animal { name: "Spike", species: "Dog", age: 3 }]
// Upper case names ["TOM", "JERRY", "SPIKE"]

在上面的代碼中,我們定義了一個(gè)Animal結(jié)構(gòu)體,其中包含了動(dòng)物的名稱、物種和年齡信息。我們使用Vec類型來(lái)存儲(chǔ)所有動(dòng)物的信息。接下來(lái),我們使用包對(duì)這些動(dòng)物進(jìn)行了一些常見(jiàn)的數(shù)據(jù)處理和轉(zhuǎn)換操作。

首先,我們計(jì)算了所有動(dòng)物的平均年齡。我們使用iter()方法對(duì)Vec進(jìn)行迭代,并使用map()方法將每個(gè)動(dòng)物的年齡提取出來(lái)。然后,我們使用sum()方法將所有的年齡相加,并將其轉(zhuǎn)換為i32類型。最后,我們將總年齡除以動(dòng)物數(shù)量,得到平均年齡。

接下來(lái),我們統(tǒng)計(jì)了每個(gè)物種的數(shù)量。我們使用HashMap類型來(lái)存儲(chǔ)物種和數(shù)量的映射關(guān)系。我們使用entry方法獲取每個(gè)物種的數(shù)量,如果該物種不存在,則插入一個(gè)新的映射關(guān)系,并將數(shù)量初始化為0。最后,我們使用filter()方法和閉包找出了所有年齡大于2歲的動(dòng)物。我們使用map()方法和閉包將所有動(dòng)物的名字轉(zhuǎn)換成大寫,然后使用collect()方法將它們收集到一個(gè)新的Vec中。最后,我們使用map()方法和閉包將所有動(dòng)物的名字轉(zhuǎn)換成大寫。

在上面的示例中,我們可以看到閉包的強(qiáng)大之處。使用閉包,我們可以輕松地對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換和處理,而不必定義大量的函數(shù)。此外,閉包還可以捕獲外部環(huán)境中的變量,使得代碼更加靈活和可讀。

閉包的語(yǔ)法

包的語(yǔ)法形式如下:

|arg1, arg2, ...| body

其中,arg1arg2...表示閉包參數(shù),body表示閉包函數(shù)體。閉包可以有多個(gè)參數(shù),也可以沒(méi)有參數(shù)。如果閉包沒(méi)有參數(shù),則可以省略||之間的內(nèi)容。

無(wú)參數(shù)閉包示例:

fn main() {
    let greet = || println!("Hello, World!");
    greet();
}
//    輸出結(jié)果:
//    Hello, World!

閉包的函數(shù)體可以是任意有效的Rust代碼,包括表達(dá)式、語(yǔ)句和控制流結(jié)構(gòu)等。在閉包中,我們可以使用外部作用域中的變量。這些變量被稱為閉包的自由變量,因?yàn)樗鼈儾皇情]包參數(shù),但是在閉包中被引用了。

閉包的自由變量示例如下:

fn main() {
    let x = 3;
    let y = 5;
    //  在這里y,就是閉包的自由變量  
    let add = |a, b| a + b + y;
    
    println!("add_once_fn: {}", add(x,y));
}
//    輸出結(jié)果:
//    13

在上面的示例中,我們定義了一個(gè)閉包add,沒(méi)用指定參數(shù)的具體類型,這里是使用到了Rust語(yǔ)言的閉包類型推導(dǎo)特性,編譯器會(huì)在調(diào)用的地方進(jìn)行類型推導(dǎo)。這里值得注意的幾點(diǎn)小技巧定義的閉包必須要有使用,否則編譯器缺少類型推導(dǎo)的上下文。當(dāng)編譯器推導(dǎo)出一種類型后,它就會(huì)一直使用該類型,和泛型有本質(zhì)的區(qū)別。

//    1. 將上面例子的pringln!注釋掉, 相當(dāng)于add閉包沒(méi)用任何引用,編譯報(bào)錯(cuò)
error[E0282]: type annotations needed
  -- > src/main.rs:13:16
   |
13 |     let add = |a, b| a + b + y;
   |                ^
   |
help: consider giving this closure parameter an explicit type
   |
13 |     let add = |a: /* Type */, b| a + b + y;
   |                 ++++++++++++
//    2. 新增打印 println!("add_once_fn: {}", add(0.5,0.6));

error[E0308]: arguments to this function are incorrect
  -- > src/main.rs:16:33
   |
16 |     println!("add_once_fn: {}", add(0.5,0.6));
   |                                 ^^^ --- --- expected integer, found floating-point number
   |                                     |
   |                                     expected integer, found floating-point number
   |
note: closure defined here
  -- > src/main.rs:13:15
   |
13 |     let add = |a, b| a + b + y;
   |               ^^^^^^

閉包可以使用三種方式之一來(lái)捕獲自由變量:

  • ? move關(guān)鍵字:將自由變量移動(dòng)到閉包內(nèi)部,使得閉包擁有自由變量的所有權(quán)。這意味著,一旦自由變量被移動(dòng),部作用域?qū)o(wú)法再次使用它。
  • ? &引用:使用引用來(lái)訪問(wèn)自由變量。這意味著,外部作用域仍然擁有自由變量的所有權(quán),并且可以在閉包之后繼續(xù)使用它。
  • ? &mut可變引用:使用可變引用來(lái)訪問(wèn)自由變量。這意味著,外部作用域仍然擁有自由變量的所有權(quán),并且可以在閉包之后繼續(xù)使用它。但是,只有一個(gè)可變引用可以存在于任意給定的時(shí)間。如果閉包中有多個(gè)可變引用,編譯器將無(wú)法通過(guò)。

下面是具有不同捕獲方式的閉包示例:

fn main() {
    let x = 10;
    let y = 20;
    
    // 使用move關(guān)鍵字捕獲自由變量
    let add = move |a:i32, b:i32| a + b + x;
    
    // 使用引用捕獲自由變量
    let sub = |a:i32, b:i32| a - b - y;
    
    // 使用可變引用捕獲自由變量
    let mut z = 30;
    let mut mul = |a:i32, b:i32| {
        z += 1;
        a * b * z
    };
    println!("add {}", add(x, y))
    println!("sub {}", sub(x, y))
    println!("mul {}", mul(x, y))
}
//    輸出結(jié)果:
// add 40
// sub -30
// mul 6200

在上面的示例中,我們定義了三個(gè)閉包:add、submul。

  • ? add使用move關(guān)鍵字捕獲了自由變量x,因此它擁有x的所有權(quán)。
  • ? sub使用引用捕獲了自由變量y,因此它只能訪問(wèn)y的值,而不能修改它。
  • ? mul使用可變引用捕獲了自由變量z,因此它可以修改z的值。在這種情況下,我們需要使用mut關(guān)鍵字來(lái)聲明可變引用。

閉包的類型

在Rust語(yǔ)言中,閉包是一種特殊的類型,被稱為FnFnMutFnOnce。這些類型用于區(qū)分閉包的捕獲方式和參數(shù)類型。

  • ? Fn:表示閉包只是借用了自由變量,不會(huì)修改它們的值。這意味著,閉包可以在不擁有自由變量所有權(quán)的情況下訪問(wèn)它們。
  • ? FnMut:表示閉包擁有自由變量的可變引用,并且可能會(huì)修改它們的值。這意味著,閉包必須擁有自由變量的所有權(quán),并且只能存在一個(gè)可變引用。
  • ? FnOnce:表示閉包擁有自由變量的所有權(quán),并且只能被調(diào)用一次。這意味著,閉包必須擁有自由變量的所有權(quán),并且只能在調(diào)用之后使用它們。

在閉包類型之間進(jìn)行轉(zhuǎn)換是非常簡(jiǎn)單的。只需要在閉包的參數(shù)列表中添加相應(yīng)的trait限定,即可將閉包轉(zhuǎn)換為特定的類型。例如,如果我們有一個(gè)Fn類型的閉包,但是需要將它轉(zhuǎn)換為FnMut類型,只需要在參數(shù)列表中添加mut關(guān)鍵字,如下所示:

fn main() {
    let x = 3;
    let y = 5;
    let add = |a:i32, b:i32| a + b;
    let mut add_mut = |a:i32, b:i32| {
        let result = a + b;
        println!("Result: {}", result);
        result
    };
    
    let add_fn: fn(i32, i32) - > i32 = add;
    let add_mut_fn: fn(i32, i32) - > i32 = add_mut;
    let add_once_fn: fn(i32, i32) - > i32 = |a:i32, b:i32| a + b + 10;
    println!("add_fn: {}", add_fn(x,y));
    println!("add_mut_fn: {}", add_mut_fn(x,y));
    println!("add_once_fn: {}", add_once_fn(x,y));
}
//    輸出結(jié)果:
// add_fn: 8
// Result: 8
// add_mut_fn: 8
// add_once_fn: 18

在上面的示例中,我們定義了三個(gè)閉包:add、add_mutadd_onceaddadd_mut都是Fn類型的閉包,但是add_mut使用了可變引用,因此它也是FnMut類型閉包。我們使用fn關(guān)鍵字將閉包轉(zhuǎn)換為函數(shù)類型,并指定參數(shù)和返回值的類型。在這種情況下,我們使用i32作為參數(shù)和返回值的類型。

閉包的應(yīng)用與實(shí)踐

閉包在Rust語(yǔ)言中廣泛應(yīng)用于函數(shù)式編程、迭代器和多線程等領(lǐng)域。在函數(shù)式編程中,閉包常常用于實(shí)現(xiàn)高階函數(shù),如map()filter()reduce()等。這些函數(shù)可以接受一個(gè)閉包作為參數(shù),然后對(duì)集合中的每個(gè)元素進(jìn)行轉(zhuǎn)換、過(guò)濾和歸約等操作。

以下是一個(gè)使用閉包實(shí)現(xiàn)map()filter()函數(shù)的示例:

fn map< T, F >(source: Vec< T >, mut f: F) - > Vec >
where
    F:Mut(T) - > T,
{
    let mut result = Vec::new();
    for item in source {
        result.push(f(item));
    }
    result
}

fn filter< T, F >(source: Vec< T >, mut f: F) - > Vec< T >
where
    F: FnMut(&T) - > bool,
{
    let mut result = Vec::new();
    for item in source {
        if f(&item) {
            result.push(item);
        }
    }
    result
}

在上面的示例中,我們定義了map()filter()函數(shù),它們接受一個(gè)閉包作為參數(shù),并對(duì)集合中的每個(gè)元素進(jìn)行轉(zhuǎn)換和過(guò)濾操作。map()函數(shù)將集合中的每個(gè)元素傳遞給閉包進(jìn)行轉(zhuǎn)換,并將轉(zhuǎn)換后的結(jié)果收集到一個(gè)新的Vec中。filter()函數(shù)將集合中的每個(gè)元素傳遞給閉包進(jìn)行過(guò)濾,并將通過(guò)過(guò)濾的元素收集到一個(gè)新的Vec中。

以下是一個(gè)使用閉包實(shí)現(xiàn)多線程的示例:

use std::thread;

fn main() {
    let mut handles = Vec::new();
    for i in 0..10 {
        let handle = thread::spawn(move || {
            println!("Thread {}: Hello, world!", i);
        });
        handles.push(handle);
    }
    for handle in handles {
        handle.join().unwrap();
    }
}
//    輸出結(jié)果:
// Thread 1: Hello, world!
// Thread 7: Hello, world!
// Thread 8: Hello, world!
// Thread 9: Hello, world!
// Thread 6: Hello, world!
// Thread 5: Hello, world!
// Thread 4: Hello, world!
// Thread 3: Hello, world!
// Thread 2: Hello, world!
// Thread 0: Hello, world!

在上面的示例中,我們使用thread::spawn()函數(shù)創(chuàng)建了10個(gè)新線程,并使用閉包將每個(gè)線程的編號(hào)傳遞給它們。在閉包中,我們使用move關(guān)鍵字將i移動(dòng)到閉包內(nèi)部,以便在創(chuàng)建線程之后,i的所有權(quán)被轉(zhuǎn)移 給了閉包。然后,我們將每個(gè)線程的句柄存儲(chǔ)在一個(gè)Vec中,并使用join()函數(shù)等待每個(gè)線程完成。

總結(jié)

Rust語(yǔ)言中的閉包是一種非常強(qiáng)大的特性,可以用于實(shí)現(xiàn)高階函數(shù)、函數(shù)式編程、迭代器和多線程等領(lǐng)域。閉包具有捕獲自由變量的能力,并且可以在閉包后繼續(xù)使用它們。在Rust語(yǔ)言中,閉包是一種特殊的類型,被稱為Fn、FnMutOnce,用于區(qū)閉包的捕獲方式和參數(shù)類型。閉包可以通過(guò)實(shí)現(xiàn)這些trait來(lái)進(jìn)行類型轉(zhuǎn)換。

盡管閉包在Rust語(yǔ)言中非常強(qiáng)大和靈活,但是使用它們時(shí)需要謹(jǐn)慎。閉包的捕獲方式和參數(shù)類型可能會(huì)導(dǎo)致所有權(quán)和可變性的問(wèn)題,尤其是在多線程環(huán)境中。因此,我們應(yīng)該在使用閉包時(shí)仔細(xì)思考,并遵循Rust語(yǔ)言的所有權(quán)和可變性規(guī)則。

總之,閉包是一種非常有用的特性,可以幫助我們編寫更加靈活和高效的代碼。如果您還沒(méi)有使用過(guò)閉包,請(qǐng)嘗試在您的項(xiàng)目中使用它們,并體驗(yàn)閉包帶來(lái)的便利和效率。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)
    +關(guān)注

    關(guān)注

    13

    文章

    4337

    瀏覽量

    85992
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3633

    瀏覽量

    93848
  • 數(shù)據(jù)處理
    +關(guān)注

    關(guān)注

    0

    文章

    610

    瀏覽量

    28599
  • rust語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3016
  • 閉包
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    2070
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    聊聊Rust與C語(yǔ)言交互的具體步驟

    rust FFI 是rust與其他語(yǔ)言互調(diào)的橋梁,通過(guò)FFI rust 可以有效繼承 C 語(yǔ)言的歷史資產(chǎn)。本期通過(guò)幾個(gè)例子來(lái)聊聊
    發(fā)表于 07-06 11:15 ?1728次閱讀

    C語(yǔ)言中預(yù)定義宏的用法和使用場(chǎng)景

    在C語(yǔ)言中,預(yù)定義宏是由編譯器提供的一組特殊標(biāo)識(shí)符,可以在程序中直接使用,無(wú)需進(jìn)行額外的定義。
    發(fā)表于 08-16 16:12 ?500次閱讀

    如何在Rust中高效地操作文件

    Rust語(yǔ)言是一種系統(tǒng)級(jí)、高性能的編程語(yǔ)言,其設(shè)計(jì)目標(biāo)是確保安全和并發(fā)性。 Rust語(yǔ)言以C和C++為基礎(chǔ),但是對(duì)于安全性和并發(fā)性做出了很大
    的頭像 發(fā)表于 09-19 11:51 ?2464次閱讀

    SQLx在Rust語(yǔ)言中的基礎(chǔ)用法和進(jìn)階用法

    SQLx是一個(gè)Rust語(yǔ)言的異步SQL執(zhí)行庫(kù),它支持多種數(shù)據(jù)庫(kù),包括MySQL、PostgreSQL、SQLite等。本教程將以MySQL數(shù)據(jù)庫(kù)為例,介紹SQLx在Rust語(yǔ)言中的基礎(chǔ)
    的頭像 發(fā)表于 09-19 14:32 ?5376次閱讀

    Rust語(yǔ)言中錯(cuò)誤處理的機(jī)制

    Rust語(yǔ)言中,錯(cuò)誤處理是一項(xiàng)非常重要的任務(wù)。由于Rust語(yǔ)言采用靜態(tài)類型檢查,在編譯時(shí)就能發(fā)現(xiàn)很多潛在的錯(cuò)誤,這使得程序員能夠更加自信和高效地開(kāi)發(fā)程序。然而,即使我們?cè)诰幾g時(shí)盡可能
    的頭像 發(fā)表于 09-19 14:54 ?1455次閱讀

    基于Rust語(yǔ)言Hash特征的基礎(chǔ)用法和進(jìn)階用法

    Rust語(yǔ)言是一種系統(tǒng)級(jí)編程語(yǔ)言,具有高性能、安全、并發(fā)等特點(diǎn),是近年來(lái)備受關(guān)注的新興編程語(yǔ)言。在Rust
    的頭像 發(fā)表于 09-19 16:02 ?1509次閱讀

    Rust語(yǔ)言中的反射機(jī)制

    Rust語(yǔ)言的反射機(jī)制指的是在程序運(yùn)行時(shí)獲取類型信息、變量信息等的能力。Rust語(yǔ)言中的反射機(jī)制主要通過(guò) Any 實(shí)現(xiàn)。 std::any::Any trait Any trait是所
    的頭像 發(fā)表于 09-19 16:11 ?2491次閱讀

    Rust語(yǔ)言如何與 InfluxDB 集成

    Rust 是一種系統(tǒng)級(jí)編程語(yǔ)言,具有高性能和內(nèi)存安全性。InfluxDB 是一個(gè)開(kāi)源的時(shí)間序列數(shù)據(jù)庫(kù),用于存儲(chǔ)、查詢和可視化大規(guī)模數(shù)據(jù)集。Rust 語(yǔ)言可以與 InfluxDB 集成,
    的頭像 發(fā)表于 09-30 16:45 ?1206次閱讀

    基于Rust語(yǔ)言中的生命周期

    Rust是一門系統(tǒng)級(jí)編程語(yǔ)言具備高效、安和并發(fā)等特,而生命周期是這門語(yǔ)言中比較重要的概念之一。在這篇教程中,我們會(huì)了解什么是命周期、為什么需要生命周期、如何使用生命周期,同時(shí)我們依然會(huì)使用老朋友
    的頭像 發(fā)表于 09-19 17:03 ?925次閱讀

    Rust 語(yǔ)言中的 RwLock內(nèi)部實(shí)現(xiàn)原理

    Rust是一種系統(tǒng)級(jí)編程語(yǔ)言,它帶有嚴(yán)格的內(nèi)存管理、并發(fā)和安全性規(guī)則,因此很受廣大程序員的青睞。RwLock(讀寫鎖)是 Rust 中常用的線程同步機(jī)制之一,本文將詳細(xì)介紹 Rust
    的頭像 發(fā)表于 09-20 11:23 ?893次閱讀

    用最簡(jiǎn)單的語(yǔ)言解釋Python的是什么?

    很藍(lán)瘦,你應(yīng)該盡量理解一下它。
    的頭像 發(fā)表于 03-21 16:33 ?2133次閱讀

    詳細(xì)介紹go語(yǔ)言中的實(shí)現(xiàn)

    什么是? 什么場(chǎng)景下會(huì)用 ? 本文對(duì) go 語(yǔ)言中
    的頭像 發(fā)表于 10-20 16:18 ?1873次閱讀

    帶你了解go語(yǔ)言中

    ? 【 導(dǎo)讀】什么是? 什么場(chǎng)景下會(huì)用 ? 本文對(duì) go 語(yǔ)言中
    的頭像 發(fā)表于 11-02 15:27 ?2469次閱讀

    谷歌開(kāi)源內(nèi)部Rust Crate審計(jì)結(jié)果

    Rust 可以輕松地將代碼封裝和共享到 crate 中,crate 是可重用的軟件組件,就像其他語(yǔ)言中一樣。我們擁抱廣泛的開(kāi)源 Rust crate 生態(tài)系統(tǒng),既利用了谷歌以外編
    的頭像 發(fā)表于 05-29 11:10 ?827次閱讀

    tokio模塊channel中的使用場(chǎng)景和優(yōu)缺點(diǎn)

    以讓不同的線程之間通過(guò)發(fā)送和接收消息來(lái)傳遞數(shù)據(jù),從而實(shí)現(xiàn)線程之間的協(xié)作和同步。 在 Rust 語(yǔ)言中,tokio 模塊的 channel 組件提供了
    的頭像 發(fā)表于 09-19 15:54 ?823次閱讀