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

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

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

CRust學(xué)習(xí)筆記:生命周期-1

jf_wN0SrCdH ? 來源:coding到燈火闌珊 ? 作者: 李明 ? 2022-12-19 09:33 ? 次閱讀

本系列文章是Jon Gjengset發(fā)布的CRust of Rust系列視頻的學(xué)習(xí)筆記,CRust of Rust是一系列持續(xù)更新的Rust中級教程。

在這篇文章中,我們將研究一個需要顯式注釋多個生命期的例子。我們還將討論不同字符串類型之間的一些差異,以及在自定義的trait上引入泛型。這個例子是根據(jù)給定的字符串和分隔符對字符串進行拆分。

創(chuàng)建一個新項目:

cargo new --lib strsplit
lib.rs中寫入如下代碼:
 1#[derive(Debug)]
 2pubstructStrSplit<'a>{
 3remainder:&'astr,
 4delimiter:&'astr,
 5}
 6
 7#[allow(dead_code)]
 8impl<'a>StrSplit<'a>{
 9pubfnnew(haystack:&'astr,delimiter:&'astr)->Self{
10Self{
11remainder:haystack,
12delimiter,
13}
14}
15}
16
17impl<'a>IteratorforStrSplit<'a>{
18typeItem=&'astr;
19
20fnnext(&mutself)->Option{
21ifletSome(next_delim)=self.remainder.find(self.delimiter){
22letuntil_remainder=&self.remainder[..next_delim];
23self.remainder=&self.remainder[next_delim+self.delimiter.len()..];
24Some(until_remainder)
25}elseifself.remainder.is_empty(){
26None
27}else{
28letrest=self.remainder;
29//為什么空字符串可以賦值給self.remainder???
30self.remainder="";
31Some(rest)
32}
33}
34}
35
36#[test]
37fnit_works(){
38lethaystack="abcde";
39letletters:Vec<_>=StrSplit::new(haystack,"").collect();
40assert_eq!(letters,vec!["a","b","c","d","e"]);
41}

StrSplit 與成員 remainder,delimiter 擁有相同的生命周期

使用fn new()方法構(gòu)建的StrSplit與傳入的參數(shù)haystack,delimiter 擁有相同的生命周期

在實現(xiàn)Iterator trait時,迭代的結(jié)果也要與StrSplit擁有相同的生命周期,是因為要在StrSplit的成員remainder上做迭代。

在第30行,為什么空字符串可以賦值給self.remainder?這是因為self.remainder的生命周期是&'a str,空字符串的生命周期是&'static str,static的生命周期一直到程序結(jié)束。 修復(fù)Bug 這里有一個bug,添加如下測試方法:

1#[test]
2fntail(){
3lethaystack="abcd";
4letletters:Vec<_>=StrSplit::new(haystack,"").collect();
5assert_eq!(letters,vec!["a","b","c","d",""]);
6}
執(zhí)行cargo test:
running 2 tests
test str_split_1::it_works ... ok
test str_split_1::tail ... FAILED
我們將struct StrSplit的成員remainder定義為Option<&'a str>類型來修復(fù)這個bug:
 1/**
 2*StrSplit與成員remainder,delimiter擁有相同的生命周期
 3*/
 4#[derive(Debug)]
 5pubstructStrSplit<'a>{
 6//使用Option
 7remainder:Option<&'a?str>,
 8delimiter:&'astr,
 9}
10
11#[allow(dead_code)]
12impl<'a>StrSplit<'a>{
13/**
14*新構(gòu)建的StrSplit與傳入的參數(shù)haystack,delimiter擁有相同的生命周期
15*/
16pubfnnew(haystack:&'astr,delimiter:&'astr)->Self{
17Self{
18remainder:Some(haystack),
19delimiter,
20}
21}
22}
23
24impl<'a>IteratorforStrSplit<'a>{
25//迭代的結(jié)果也要與StrSplit擁有相同的生命周期,是因為要在StrSplit的成員remainder上做迭代。
26typeItem=&'astr;
27
28fnnext(&mutself)->Option{
29//這里為什么用Some(refmutremainder),而不用Some(&mutrefmainder)???
30ifletSome(refmutremainder)=self.remainder{
31ifletSome(next_delim)=remainder.find(self.delimiter){
32letuntil_remainder=&remainder[..next_delim];
33*remainder=&remainder[next_delim+self.delimiter.len()..];
34Some(until_remainder)
35}else{
36self.remainder.take()
37}
38}else{
39None
40}
41}
42}
43
44#[test]
45fnit_works(){
46lethaystack="abcde";
47letletters:Vec<_>=StrSplit::new(haystack,"").collect();
48assert_eq!(letters,vec!["a","b","c","d","e"]);
49}
50
51#[test]
52fntail(){
53lethaystack="abcd";
54letletters:Vec<_>=StrSplit::new(haystack,"").collect();
55assert_eq!(letters,vec!["a","b","c","d",""]);
56}
執(zhí)行cargo test,測試通過:
running 2 tests
test str_split_2::tail ... ok
test str_split_2::it_works ... ok
在上面代碼的第30行,為什么用Some(ref mut remainder),而不是用Some(&mut refmainder)?這是因為在進行Some(&mut remainder)=self.remainder模式匹配時,remainder會被自動解引用成str類型,而不是可變的&str類型。 另一種寫法
 1impl<'a>IteratorforStrSplit<'a>{
 2//迭代的結(jié)果也要與StrSplit擁有相同的生命周期,是因為要在StrSplit的成員remainder上做迭代。
 3typeItem=&'astr;
 4
 5fnnext(&mutself)->Option{
 6//為什么不可以這么寫???
 7letremainder=&mutself.remainder?;
 8ifletSome(next_delim)=remainder.find(self.delimiter){
 9letuntil_remainder=&remainder[..next_delim];
10*remainder=&remainder[next_delim+self.delimiter.len()..];
11Some(until_remainder)
12}else{
13self.remainder.take()
14}
15}
16}
17

在迭代器的next方法里嘗試換一種寫法,編譯器檢查通過,但是執(zhí)行測試不通過。也就是上面代碼的第7行,為什么不可以這么寫?

self.remainder是Option<&'a str>類型,這里的泛型是引用。所以在執(zhí)行unwrap(),expect()或?時,會將Option里的引用Copy一份出來賦值給remainder,然后在這個新的remainder上作可變引用,而self.remainder沒有任何變化。

我們可以使用Option的as_mut()方法,因為它返回的是Option<&mut T>:

1fnnext(&mutself)->Option{
2//為什么這么寫不可以???
3//letremainder=&mutself.remainder?;
4
5letremainder=self.remainder.as_mut()?;
6......
7}

得到了一個self.remainder的可變引用,因此測試通過。

在下一篇文章中,我們通過更多的例子來繼續(xù)學(xué)習(xí)Rust的生命周期。

審核編輯:湯梓紅

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

    關(guān)注

    1

    文章

    567

    瀏覽量

    20432
  • 生命周期
    +關(guān)注

    關(guān)注

    0

    文章

    15

    瀏覽量

    7456
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    228

    瀏覽量

    6523

原文標(biāo)題:CRust學(xué)習(xí)筆記:生命周期-1

文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    基于Rust語言中的生命周期

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

    AutoScaling 生命周期掛鉤功能

    摘要: AutoScaling 伸縮組實例管理功能全面升級,新上線生命周期掛鉤(LifecycleHook)功能,方便用戶更加靈活地管理伸縮組內(nèi)實例。使用生命周期掛鉤可以在伸縮組發(fā)生伸縮活動時將伸縮
    發(fā)表于 06-27 17:13

    HarmonyOS應(yīng)用開發(fā)-PageAbility生命周期

    pageAbility的生命周期如下圖所示:在代碼中通過調(diào)用下列方法實現(xiàn)生命周期操作:onShow() :Ability由后臺不可見狀態(tài)切換到前臺可見狀態(tài)調(diào)用onShow方法,此時用戶在屏幕可以看到
    發(fā)表于 10-17 11:11

    在S32G2 RM中有“生命周期”,生命周期的完整含義是什么?

    在S32G2 RM中,有“生命周期”。生命周期的完整含義是什么,我們應(yīng)該如何使用它?
    發(fā)表于 04-23 10:37

    一文讀懂Android Activity生命周期

    正常情況下Activity的生命周期: Activity的生命周期大概可以歸為三部分 整個的生命周期:onCreate()可以設(shè)置所有的“全局”狀態(tài), onDestory()可以釋放所有的資源 可見
    發(fā)表于 05-30 01:03 ?1545次閱讀

    基于延長WSN生命周期的LEACH算法的改進

    基于延長WSN生命周期的LEACH算法的改進(開關(guān)電源技術(shù)與設(shè)計pdf百度云)-基于延長WSN生命周期的LEACH算法的改進? ? ? ? ? ? ? ? ? ??
    發(fā)表于 09-15 11:17 ?14次下載
    基于延長WSN<b class='flag-5'>生命周期</b>的LEACH算法的改進

    CRust學(xué)習(xí)筆記生命周期-2

    本系列文章是Jon Gjengset發(fā)布的CRust of Rust系列視頻的學(xué)習(xí)筆記,CRust of Rust是一系列持續(xù)更新的Rust中級教程。
    的頭像 發(fā)表于 12-19 09:34 ?788次閱讀

    CRust學(xué)習(xí)筆記:聲明宏

    本系列文章是Jon Gjengset發(fā)布的CRust of Rust系列視頻的學(xué)習(xí)筆記,CRust of Rust是一系列持續(xù)更新的Rust中級教程。
    的頭像 發(fā)表于 01-06 14:37 ?752次閱讀

    CRust學(xué)習(xí)筆記:智能指針和內(nèi)部可變性

    本系列文章是Jon Gjengset發(fā)布的CRust of Rust系列視頻的學(xué)習(xí)筆記,CRust of Rust是一系列持續(xù)更新的Rust中級教程。
    的頭像 發(fā)表于 01-29 14:58 ?767次閱讀

    Vue入門Vue的生命周期

    .生命周期 4.1生命周期是什么 Vue的生命周期, 就是Vue實例從創(chuàng)建到銷毀的過程.
    的頭像 發(fā)表于 02-06 16:16 ?806次閱讀
    Vue入門Vue的<b class='flag-5'>生命周期</b>

    編譯器的標(biāo)準(zhǔn)生命周期

    編譯器的標(biāo)準(zhǔn)生命周期
    發(fā)表于 03-14 19:06 ?0次下載
    編譯器的標(biāo)準(zhǔn)<b class='flag-5'>生命周期</b>

    編譯器的標(biāo)準(zhǔn)生命周期

    編譯器的標(biāo)準(zhǔn)生命周期
    發(fā)表于 07-05 19:32 ?0次下載
    編譯器的標(biāo)準(zhǔn)<b class='flag-5'>生命周期</b>

    數(shù)據(jù)包的生命周期

    電子發(fā)燒友網(wǎng)站提供《數(shù)據(jù)包的生命周期.pdf》資料免費下載
    發(fā)表于 10-13 14:44 ?0次下載

    鴻蒙開發(fā):【PageAbility的生命周期

    PageAbility生命周期是PageAbility被調(diào)度到INACTIVE、ACTIVE、BACKGROUND等各個狀態(tài)的統(tǒng)稱。PageAbility生命周期流轉(zhuǎn)及狀態(tài)說明見如下圖1、表1
    的頭像 發(fā)表于 06-17 10:05 ?624次閱讀
    鴻蒙開發(fā):【PageAbility的<b class='flag-5'>生命周期</b>】

    鴻蒙開發(fā)組件:DataAbility的生命周期

    應(yīng)用開發(fā)者可以根據(jù)業(yè)務(wù)場景實現(xiàn)data.js/data.ets中的生命周期相關(guān)接口。DataAbility生命周期接口說明見下表。
    的頭像 發(fā)表于 06-20 09:39 ?329次閱讀