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

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

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

Stream的核心概念

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

Stream 是 Rust 語(yǔ)言中的一種迭代器,它可以使得我們?cè)谔幚頂?shù)據(jù)時(shí)更加高效、靈活。Stream 不僅可以處理大量數(shù)據(jù),還可以進(jìn)行異步操作,這使得它在處理網(wǎng)絡(luò)請(qǐng)求等 IO 操作時(shí)非常有用。

Stream 的核心概念是將數(shù)據(jù)視為流,每次處理一個(gè)元素,而不是將整個(gè)數(shù)據(jù)集加載到內(nèi)存中。這樣可以避免內(nèi)存占用過(guò)大的問(wèn)題,同時(shí)也能夠提高程序的效率。

基礎(chǔ)用法

創(chuàng)建 Stream

在 Rust 中,我們可以使用iter方法來(lái)創(chuàng)建 Stream。例如,我們可以使用以下代碼來(lái)創(chuàng)建一個(gè)包含 1 到 5 的 Stream:

let stream = (1..5).into_iter();

這里使用了into_iter方法將一個(gè)范圍轉(zhuǎn)換為 Stream。

遍歷 Stream

遍歷 Stream 可以使用for_each方法,例如:

stream.for_each(|x| println!("{}", x));

這里使用了閉包來(lái)打印每個(gè)元素。

過(guò)濾 Stream

我們可以使用filter方法來(lái)過(guò)濾 Stream 中的元素,例如:

let stream = (1..5).into_iter().filter(|x| x % 2 == 0);

這里使用了閉包來(lái)判斷元素是否為偶數(shù)。

映射 Stream

我們可以使用map方法來(lái)對(duì) Stream 中的元素進(jìn)行映射,例如:

let stream = (1..5).into_iter().map(|x| x * 2);

這里使用了閉包來(lái)將每個(gè)元素乘以 2。

合并 Stream

我們可以使用chain方法來(lái)合并多個(gè) Stream,例如:

let stream1 = (1..3).into_iter();
let stream2 = (4..6).into_iter();
let stream = stream1.chain(stream2);

這里使用了chain方法將兩個(gè) Stream 合并為一個(gè)。

排序 Stream

我們可以使用sorted方法來(lái)對(duì) Stream 中的元素進(jìn)行排序,例如:

let stream = vec![3, 1, 4, 1, 5, 9].into_iter().sorted();

這里使用了sorted方法將 Stream 中的元素按照升序排序。

取前 n 個(gè)元素

我們可以使用take方法來(lái)取 Stream 中的前 n 個(gè)元素,例如:

let stream = (1..5).into_iter().take(3);

這里使用了take方法取 Stream 中的前 3 個(gè)元素。

跳過(guò)前 n 個(gè)元素

我們可以使用skip方法來(lái)跳過(guò) Stream 中的前 n 個(gè)元素,例如:

let stream = (1..5).into_iter().skip(2);

這里使用了skip方法跳過(guò) Stream 中的前 2 個(gè)元素。

統(tǒng)計(jì)元素個(gè)數(shù)

我們可以使用count方法來(lái)統(tǒng)計(jì) Stream 中的元素個(gè)數(shù),例如:

let stream = (1..5).into_iter();
let count = stream.count();
println!("{}", count);

這里使用了count方法統(tǒng)計(jì) Stream 中的元素個(gè)數(shù),并打印出來(lái)。

進(jìn)階用法

異步 Stream

在 Rust 中,我們可以使用futures庫(kù)來(lái)創(chuàng)建異步 Stream。例如,我們可以使用以下代碼來(lái)創(chuàng)建一個(gè)異步 Stream:

use futures::stream::StreamExt;

let stream = futures::stream::iter(vec![1, 2, 3]);

這里使用了iter方法來(lái)創(chuàng)建一個(gè)包含 1 到 3 的異步 Stream。

并行 Stream

在 Rust 中,我們可以使用rayon庫(kù)來(lái)創(chuàng)建并行 Stream。例如,我們可以使用以下代碼來(lái)創(chuàng)建一個(gè)并行 Stream:

rayon = "1.7"
use rayon::iter::ParallelIterator;

let stream = (1..5).into_par_iter();

這里使用了into_par_iter方法將一個(gè)范圍轉(zhuǎn)換為并行 Stream。

處理 Stream 中的錯(cuò)誤

在處理 Stream 時(shí),有時(shí)候會(huì)出現(xiàn)錯(cuò)誤。我們可以使用Result來(lái)處理這些錯(cuò)誤。例如,我們可以使用以下代碼來(lái)處理 Stream 中的錯(cuò)誤:

let stream = vec![1, 2, "a", 3].into_iter().map(|x| {
    if let Some(y) = x.downcast_ref::< i32 >() {
        Ok(*y)
    } else {
        Err("not a number")
    }
});

for item in stream {
    match item {
        Ok(x) = > println!("{}", x),
        Err(e) = > println!("{}", e),
    }
}

這里使用了downcast_ref方法將元素轉(zhuǎn)換為i32類(lèi)型,如果轉(zhuǎn)換失敗則返回錯(cuò)誤。

無(wú)限 Stream

在 Rust 中,我們可以使用repeat方法來(lái)創(chuàng)建一個(gè)無(wú)限 Stream。例如,我們可以使用以下代碼來(lái)創(chuàng)建一個(gè)包含無(wú)限個(gè) 1 的 Stream:

let stream = std::iter::repeat(1);

這里使用了repeat方法將 1 重復(fù)無(wú)限次。

處理 Stream 中的重復(fù)元素

在處理 Stream 時(shí),有時(shí)候會(huì)出現(xiàn)重復(fù)元素的情況。我們可以使用dedup方法來(lái)去除 Stream 中的重復(fù)元素。例如:

let stream = vec![1, 2, 2, 3, 3, 3].into_iter().dedup();

這里使用了dedup方法去除 Stream 中的重復(fù)元素。

處理 Stream 中的空元素

在處理 Stream 時(shí),有時(shí)候會(huì)出現(xiàn)空元素的情況。我們可以使用filter方法來(lái)過(guò)濾掉 Stream 中的空元素。例如:

let stream = vec![1, 2, "", 3, "", ""].into_iter().filter(|x| !x.is_empty());

這里使用了filter方法過(guò)濾掉 Stream 中的空元素。

處理 Stream 中的 None 值

在處理 Stream 時(shí),有時(shí)候會(huì)出現(xiàn) None 值的情況。我們可以使用filter_map方法來(lái)過(guò)濾掉 Stream 中的 None 值。例如:

let stream = vec![Some(1), None, Some(2), None, Some(3)].into_iter().filter_map(|x| x);

這里使用了filter_map方法過(guò)濾掉 Stream 中的 None 值。

處理 Stream 中的重復(fù)元素

在處理 Stream 時(shí),有時(shí)候會(huì)出現(xiàn)重復(fù)元素的情況。我們可以使用dedup_by方法來(lái)去除 Stream 中的重復(fù)元素。例如:

let stream = vec!["a", "b", "bc", "cd", "de", "ef"].into_iter().dedup_by(|a, b| a.chars().next() == b.chars().next());

這里使用了dedup_by方法去除 Stream 中的重復(fù)元素,去重條件是元素的首字母相同。

最佳實(shí)踐

在使用 Stream 時(shí),我們應(yīng)該注意以下幾點(diǎn):

  • ? 盡量使用異步 Stream 來(lái)處理 IO 操作,這樣可以避免阻塞線程。
  • ? 在處理大量數(shù)據(jù)時(shí),應(yīng)該使用并行 Stream 來(lái)提高程序的效率。
  • ? 在處理錯(cuò)誤時(shí),應(yīng)該使用Result來(lái)處理錯(cuò)誤,避免程序崩潰。
  • ? 在處理無(wú)限 Stream 時(shí),應(yīng)該使用take方法限制 Stream 的大小,避免程序無(wú)限運(yùn)行。
  • ? 在處理重復(fù)元素時(shí),應(yīng)該使用dedupdedup_by方法去除重復(fù)元素,避免重復(fù)計(jì)算。

示例代碼

下面是一個(gè)完整的示例代碼,演示了如何使用 Stream 來(lái)處理數(shù)據(jù):

itertools = "0.10.5"
rayon = "1.7"
futures = "0.3.28"
use futures::stream::StreamExt;
use itertools::Itertools;
use rayon::iter::ParallelIterator;

fn main() {
    // 創(chuàng)建Stream
    let stream = (1..5).into_iter();

    // 遍歷Stream
    stream.for_each(|x| println!("{}", x));

    // 過(guò)濾Stream
    let stream = (1..5).into_iter().filter(|x| x % 2 == 0);
    stream.for_each(|x| println!("{}", x));

    // 映射Stream
    let stream = (1..5).into_iter().map(|x| x * 2);
    stream.for_each(|x| println!("{}", x));

    // 合并Stream
    let stream1 = (1..3).into_iter();
    let stream2 = (4..6).into_iter();
    let stream = stream1.chain(stream2);
    stream.for_each(|x| println!("{}", x));

    // 排序Stream
    let stream = vec![3, 1, 4, 1, 5, 9].into_iter().sorted();
    stream.for_each(|x| println!("{}", x));

    // 取前n個(gè)元素
    let stream = (1..5).into_iter().take(3);
    stream.for_each(|x| println!("{}", x));

    // 跳過(guò)前n個(gè)元素
    let stream = (1..5).into_iter().skip(2);
    stream.for_each(|x| println!("{}", x));

    // 統(tǒng)計(jì)元素個(gè)數(shù)
    let stream = (1..5).into_iter();
    let count = stream.count();
    println!("{}", count);

    // 異步Stream
    let stream = futures::stream::iter(vec![1, 2, 3]);
    futures::executor::block_on(async {
        stream.for_each(|x| async move {
            println!("{}", x);
        }).await;
    });

    // 并行Stream
    let stream = (1..5).into_par_iter();
    stream.for_each(|x| println!("{}", x));

    // 處理Stream中的錯(cuò)誤
    let stream = vec![1, 2, "a", 3].into_iter().map(|x| {
        if let Some(y) = x.downcast_ref::< i32 >() {
            Ok(*y)
        } else {
            Err("not a number")
        }
    });

    for item in stream {
        match item {
            Ok(x) = > println!("{}", x),
            Err(e) = > println!("{}", e),
        }
    }

    // 無(wú)限Stream
    let stream = std::iter::repeat(1).take(5);
    stream.for_each(|x| println!("{}", x));

    // 處理Stream中的重復(fù)元素
    let stream = vec![1, 2, 2, 3, 3, 3].into_iter().dedup();
    stream.for_each(|x| println!("{}", x));

    // 處理Stream中的空元素
    let stream = vec![1, 2, "", 3, "", ""].into_iter().filter(|x| !x.is_empty());
    stream.for_each(|x| println!("{}", x));

    // 處理Stream中的None值
    let stream = vec![Some(1), None, Some(2), None, Some(3)].into_iter().filter_map(|x| x);
    stream.for_each(|x| println!("{}", x));

    // 處理Stream中的重復(fù)元素
    let stream = vec!["a", "b", "bc", "cd", "de", "ef"].into_iter().dedup_by(|a, b| a.chars().next() == b.chars().next());
    stream.for_each(|x| println!("{}", x));
}

總結(jié)

Stream 是 Rust 語(yǔ)言中非常重要的一個(gè)概念,它可以使得我們?cè)谔幚頂?shù)據(jù)時(shí)更加高效、靈活。在使用 Stream 時(shí),我們應(yīng)該注意異步、并行、錯(cuò)誤處理、無(wú)限 Stream、重復(fù)元素等問(wèn)題,這樣才能寫(xiě)出高效、健壯的程序。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(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)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7048

    瀏覽量

    89077
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4790

    瀏覽量

    68654
  • Stream
    +關(guān)注

    關(guān)注

    0

    文章

    20

    瀏覽量

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

    關(guān)注

    0

    文章

    57

    瀏覽量

    3009
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Stream模塊的基礎(chǔ)用法和進(jìn)階用法

    在 Rust 語(yǔ)言中,Tokio 是一個(gè)非常流行的異步編程框架。它提供了一系列的模塊,其中最常用的就是 Stream 模塊。Stream 模塊允許我們以異步的方式處理數(shù)據(jù)流,這在很多情況下非常
    的頭像 發(fā)表于 09-19 15:33 ?1207次閱讀

    Stream API原理介紹

    原理介紹 Stream API 的核心Stream 接口,它表示一組元素的序列,可以按需進(jìn)行計(jì)算。Stream 接口提供了大量的中間操作和終端操作,可以用于過(guò)濾、映射、排序、聚合
    的頭像 發(fā)表于 09-30 15:31 ?719次閱讀

    Redis Stream應(yīng)用案例

    摘要: Redis Stream Redis最新的大版本5.0已經(jīng)RC1了,其中最重要的Feature莫過(guò)于Redis Stream了,關(guān)于Redis Stream的基本使用介紹和設(shè)計(jì)理念可以看我
    發(fā)表于 06-26 17:15

    請(qǐng)問(wèn)BF60x中PVP編程stream是一個(gè)什么概念?

    1:stream 是一個(gè)什么概念。是不是特指PVP的輸入和輸出流?一個(gè)pvp的初始化過(guò)程只需要調(diào)用兩次adi_pvp_OpenStream?一次給輸入一次給輸出? 比如如下函數(shù)
    發(fā)表于 08-27 11:51

    請(qǐng)問(wèn)AXI4-Stream到Video核心的技巧有什么?

    大家好。我遇到了xilinx視頻內(nèi)核的問(wèn)題,并試圖解決這個(gè)問(wèn)題好幾周但都失敗了。有人能給我一些關(guān)于AXI4-Stream到Video核心的技巧嗎?我試圖在我的項(xiàng)目中實(shí)現(xiàn)Video Scaler核心
    發(fā)表于 11-08 09:53

    git的三個(gè)核心概念詳解

    git的三個(gè)核心概念(工作區(qū),版本庫(kù)stage,版本庫(kù)master)
    發(fā)表于 12-24 07:17

    AXI-stream數(shù)據(jù)傳輸過(guò)程

      AXI4-Stream跟AXI4的區(qū)別在于AXI4-Stream沒(méi)有ADDR接口,這樣就不涉及讀寫(xiě)數(shù)據(jù)的概念了,只有簡(jiǎn)單的發(fā)送與接收說(shuō)法,減少了延時(shí),允許無(wú)限制的數(shù)據(jù)突發(fā)傳輸規(guī)模
    發(fā)表于 01-08 16:52

    Media Stream Processor Environ

    MSP ConsortiumM.100 Revision 1.6Media Stream Processor EnvironmentSpecification This document
    發(fā)表于 06-26 10:10 ?15次下載

    AXI-Stream代碼

    AXI-Stream代碼詳解 AXI4-Stream跟AXI4的區(qū)別在于AXI4-Stream沒(méi)有ADDR接口,這樣就不涉及讀寫(xiě)數(shù)據(jù)的概念了,只有簡(jiǎn)單的發(fā)送與接收說(shuō)法,減少了延時(shí),允許
    的頭像 發(fā)表于 11-05 17:40 ?3560次閱讀
    AXI-<b class='flag-5'>Stream</b>代碼

    Kafka的核心概念

    Kafka 是主流的消息流系統(tǒng),其中的概念還是比較多的,下面通過(guò)圖示的方式來(lái)梳理一下 Kafka 的核心概念,以便在我們的頭腦中有一個(gè)清晰的認(rèn)識(shí)。
    的頭像 發(fā)表于 06-20 14:24 ?969次閱讀

    關(guān)于AXI4-Stream協(xié)議總結(jié)分享

    XI4-Stream跟AXI4的區(qū)別就是AXI4-Stream去除了地址線,這樣就不涉及讀寫(xiě)數(shù)據(jù)的概念了,只有簡(jiǎn)單的發(fā)送與接收說(shuō)法,減少了延時(shí)。由于AXI4-Stream協(xié)議(amba
    的頭像 發(fā)表于 06-23 10:08 ?2319次閱讀

    ARM SMMU Data structures之Stream Table

    incoming transaction的StreamID可以找到一個(gè)STE。SMMU支持兩種Stream table格式,格式由Stream table base registers設(shè)置。
    的頭像 發(fā)表于 05-11 09:22 ?1379次閱讀
    ARM SMMU Data structures之<b class='flag-5'>Stream</b> Table

    淺析Stream里的隱式轉(zhuǎn)換

    Stream、Flow是在電路描述里經(jīng)常用到的對(duì)象。
    的頭像 發(fā)表于 05-15 17:36 ?479次閱讀
    淺析<b class='flag-5'>Stream</b>里的隱式轉(zhuǎn)換

    Stream-it!-RZ-V2快速入門(mén)指南

    Stream-it! - RZ-V2 快速入門(mén)指南
    發(fā)表于 07-10 18:58 ?0次下載
    <b class='flag-5'>Stream</b>-it!-RZ-V2快速入門(mén)指南

    Java的Stream的常用知識(shí)

    什么是Stream 生產(chǎn)線 Stream就像處理生產(chǎn)流水線一樣去工作,傳送帶就是Stream的管道,每個(gè)工廠關(guān)注直接的生產(chǎn),將上游產(chǎn)品加工成下游需要的產(chǎn)品。為什么Stream比傳統(tǒng)的處
    的頭像 發(fā)表于 10-11 15:45 ?467次閱讀
    Java的<b class='flag-5'>Stream</b>的常用知識(shí)