2020 Rust 入門 生命周期

rust.jpeg

生命周期

  • Rust 中每一個引用都有其生命周期织堂,也就是引用保持有效的作用域颓遏。大部分時候生命周期都是隱含并可以推斷的狸剃,有點類似 rust 的類型推斷付枫。
  • 生命周期的主要目標(biāo)是避免懸垂指針烹玉,這點應(yīng)該 rust 優(yōu)勢吧,可以將一些
  • Rust 編譯器使用借用檢查器來檢查生命周期是否有效阐滩。
fn main(){
    let r;
    {
        let x = 5;
        r = &x;
    }

    println!("r = {}",r);
}

Rust 之所以大家愿意放棄 cpp 而投身到 rust 的原因就是 rust 能夠兼顧效率和安全二打。安全是在編譯過程檢查。

  |
5 |         r = &x;
  |         ^^^^^^ borrowed value does not live long enough
6 |     }
  |     - `x` dropped here while still borrowed
7 |
8 |     println!("r = {}",r);
  |                       - borrow later used here

這個應(yīng)該不難理解叶眉,r 是指向 x 的內(nèi)存地址的引用址儒,x 在離開作用域 會 drop 掉 x 內(nèi)存,也就是釋放 r 所引用的內(nèi)存衅疙,所以當(dāng)離開莲趣。

函數(shù)中生命周期

fn longest(x:&str,y:&str) -> &str {
    if x.len() > y.len(){
        x
    }else{
        y
    }
}
--> src/main.rs:1:30
  |
1 | fn longest(x:&str,y:&str) -> &str {
  |                              ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`

傳入 x 和 y 都是引用,返回也是引用饱溢,為了保證返回的引用不是懸垂指針喧伞,所以告訴編譯器生命周期需要滿足參數(shù)的生命周期要大于返回值生命周期。

fn longest<'a>(x:&'a str,y:&'a str) -> &'a str {
    if x.len() > y.len(){
        x
    }else{
        y
    }
}

fn main(){
    let s1 = String::from("hello");
    let s2 = String::from("world");

    let res = longest(s1.as_str(), s2.as_str());

    println!("res = {}",res);
}

看起來有點特殊绩郎,聲明一下生命周期潘鲫。這也就是說明 rust 在編譯過程的安全性。

fn get_str<'a>(x: &'a str, y: &str) -> &'a str{
    x
}

因為 get_str 返回值 str zhi'y

fn get_str_one<'a>(x:&'a str,y:&'a str) -> &'a str{
    let r = String::from("hello");
    r.as_str()
}

結(jié)構(gòu)體聲明周期

#[derive(Debug)]
struct Tut {
    title: &str,
}
#[derive(Debug)]
struct Tut<'a> {
    title: &'a str,
}
#[derive(Debug)]
struct Tut<'a> {
    title: &'a str,
}

fn main(){
    let s1 = String::from("hello");
    let s2 = String::from("world");

    let res = longest(s1.as_str(), s2.as_str());

    println!("res = {}",res);

    let vue = String::from("vue");
    let vueTut = Tut{title:&vue};
    println!("a = {:#?}",vueTut)
}

生命周期省略

  • 沒有生命周期注解卻能夠編譯肋杖,rust 團隊將很明確的模式進行簡化即使不聲明生命周期
fn get_str_two(s:&str) -> &str{
    s
}
  • 編譯器會根據(jù)可以省略生命周期聲明的 3條規(guī)則來推斷生命周期溉仑,如果不滿足就會要求開放人員指定生命周期給出錯誤提示,還要補充說明一點就是生命周期注解省略規(guī)則適用于 fn 定義和 impl 塊定義状植。
    開始介紹 3 個省略原則前浊竟,介紹用于理解規(guī)則的兩個概念輸入生命周期輸出生命周期怨喘,函數(shù)或方法的參數(shù)的生命周期稱為輸入生命周期。而返回值的生命周期稱為輸出生命周期振定。

    1. 每一個引用的參數(shù)都有自己生命周期參數(shù)
      一個引用參數(shù)函數(shù)必怜,fn foo<'a>(x:&'a u32)
      兩個引用參數(shù)的函數(shù) fn bar<'a,'b>(x: &'a u32, y:&'b u32)
    2. 如果只有一個輸入生命周期參數(shù),那么被賦予所有輸出生命周期參數(shù)
      fn foo(x:&i32)->&i32 就等價于 fn<'a>(x:&a' i32)-> &'a i32
    3. 如果方法有多個輸入生命周期參數(shù)后频,不過其中之一因為方法的緣故為&self或者&mut self 那么self 的生命周期被賦予所有輸出生命周期參數(shù)梳庆,例子在下面來看
#[derive(Debug)]
struct Tut<'a> {
    title: &'a str,
}
impl<'a> Tut<'a>{
    fn do_something(&self)->i32{
        3
    }
}
fn main(){

    let react = String::from("react");
    let reactTut = Tut{title:&react};
    println!("{}",reactTut.do_something());
}

do_something 方法里沒有聲明生命周期,

impl<'a> Tut<'a>{
    fn do_something(&self)->i32{
        3
    }
    fn do_something_1(&self,s:&str)->&str{
        self.title
    }

    fn do_something_2(&self,s:&str)->&str{
        s
    }
}
impl<'a> Tut<'a>{
    fn do_something(&self)->i32{
        3
    }
    fn do_something_1(&self,s:&str)->&str{
        self.title
    }

    fn do_something_2<'b>(&self,s:&'b str)->&'b str{
        s
    }
}

靜態(tài)生命周期

定義方式'static,其生命周期存活于整個程序期間卑惜,所有的字符字面值都擁有static 生命周期膏执。有點類似全局變量。

use std::fmt::Display;
fn func<'a,T:Display>(x:&'a str,y:&'a str, ann:T)-> &'a str{
    println!("ann is {}",ann);
    if x.len() < y.len(){
        x
    }else{
        y
    }
}
fn func<'a,T:Display>(x:&'a str,y:&'a str, ann:T)-> &'a str{
    println!("ann is {}",ann);
    if x.len() < y.len(){
        x
    }else{
        y
    }
}
let str1 = String::from("vue");
let str2 = String::from("react");
let ann = 129;
let res = func(str1.as_str(), str2.as_str(), ann);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末露久,一起剝皮案震驚了整個濱河市胧后,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抱环,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纸巷,死亡現(xiàn)場離奇詭異镇草,居然都是意外死亡,警方通過查閱死者的電腦和手機瘤旨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門梯啤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人存哲,你說我怎么就攤上這事因宇。” “怎么了祟偷?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵察滑,是天一觀的道長。 經(jīng)常有香客問我修肠,道長贺辰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任嵌施,我火速辦了婚禮饲化,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吗伤。我一直安慰自己吃靠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布足淆。 她就那樣靜靜地躺著巢块,像睡著了一般礁阁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夕冲,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天氮兵,我揣著相機與錄音,去河邊找鬼歹鱼。 笑死泣栈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弥姻。 我是一名探鬼主播南片,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼庭敦!你這毒婦竟也來了疼进?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤秧廉,失蹤者是張志新(化名)和其女友劉穎伞广,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疼电,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡嚼锄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔽豺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片区丑。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖修陡,靈堂內(nèi)的尸體忽然破棺而出沧侥,到底是詐尸還是另有隱情,我是刑警寧澤魄鸦,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布宴杀,位于F島的核電站,受9級特大地震影響拾因,放射性物質(zhì)發(fā)生泄漏婴氮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一盾致、第九天 我趴在偏房一處隱蔽的房頂上張望主经。 院中可真熱鬧,春花似錦庭惜、人聲如沸罩驻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惠遏。三九已至砾跃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間节吮,已是汗流浹背抽高。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留透绩,地道東北人翘骂。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像帚豪,于是被迫代替她去往敵國和親碳竟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容