解析Rust?struct?中的生命周期
最近在用rust 寫(xiě)一個(gè)redis的數(shù)據(jù)校驗(yàn)工具。redis-rs中具備 redis::ConnectionLike trait,借助它可以較好的來(lái)抽象校驗(yàn)過(guò)程。在開(kāi)發(fā)中,不免要定義struct 中的某些元素為 trait object,從而帶來(lái)一些rust語(yǔ)言中的生命周期問(wèn)題。
本文不具體討論 redis的數(shù)據(jù)校驗(yàn)過(guò)程,通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)聊聊 struct 中 trait object 元素的生命周期問(wèn)題。
首先來(lái)定義一個(gè) base trait,該 trait 中只包含一個(gè)函數(shù),返回String類型。
pub trait Base { fn say(&self) -> String; }
接下來(lái),定義兩個(gè)實(shí)現(xiàn)了 Base trait 的 struct AFromBase 和 BFromBase
pub struct AFromBase { content: String, } impl Base for AFromBase { fn say(&self) -> String { self.content.clone() } } pub struct BFromBase { text: String, } impl Base for BFromBase { fn say(&self) -> String { self.text.clone() } }
接下來(lái),定義一個(gè)struct 包含兩個(gè) Base trait 的 trait object ,然后實(shí)現(xiàn)一個(gè)函數(shù)是 say 函數(shù)輸出的字符串的拼接結(jié)果.
按照其他沒(méi)有生命周期語(yǔ)言的編寫(xiě)習(xí)慣,直覺(jué)上這么寫(xiě)
pub struct AddTowBase { a: &mut dyn Base, b: &mut dyn Base, } impl AddTowBase { fn add(&self) -> String { let result = self.a.say() + &self.b.say(); result } }
最后,搞個(gè)main函數(shù)驗(yàn)證一下。
完整代碼如下
pub trait Base { fn say(&self) -> String; } pub struct AFromBase { content: String, } impl Base for AFromBase { fn say(&self) -> String { self.content.clone() } } pub struct BFromBase { text: String, } impl Base for BFromBase { fn say(&self) -> String { self.text.clone() } } pub struct AddTowBase { a: &mut dyn Base, b: &mut dyn Base, } impl<'a> AddTowBase<'a> { fn add(&self) -> String { let result = self.a.say() + &self.b.say(); result } } fn main() { let mut a = AFromBase { content: "baseA".to_string(), }; let mut b = BFromBase { text: "baseB".to_string(), }; let addtow = AddTowBase { a: &mut a, b: &mut b, }; let r = addtow.add(); println!("{}", r); }
很遺憾,以上代碼是不能編譯通過(guò)的,編譯時(shí)報(bào)如下錯(cuò)誤
error[E0106]: missing lifetime specifier --> examples/lifetimeinstruct.rs:26:8 | 26 | a: &mut dyn Base, | ^ expected named lifetime parameter | help: consider introducing a named lifetime parameter | 25 ~ pub struct AddTowBase<'a> { 26 ~ a: &'a mut dyn Base, | error[E0106]: missing lifetime specifier --> examples/lifetimeinstruct.rs:27:8 | 27 | b: &mut dyn Base, | ^ expected named lifetime parameter | help: consider introducing a named lifetime parameter | 25 ~ pub struct AddTowBase<'a> { 26 | a: &mut dyn Base, 27 ~ b: &'a mut dyn Base, | For more information about this error, try `rustc --explain E0106`. error: could not compile `wenpan-rust` due to 2 previous errors
編譯器給出的提示很明確,要在 trait object 上添加生命周期參數(shù),確保 struct 和他的 trait object 元素在同一生命周期,避免懸垂指針。
我們按照編譯器的提示修改代碼
pub struct AddTowBase<'a> { a: &'a mut dyn Base, b: &'a mut dyn Base, } impl<'a> AddTowBase<'a> { fn add(self) -> String { let result = self.a.say() + &self.b.say(); result } }
代碼順利通過(guò)編譯。
rust 的生命周期保證了內(nèi)存的安全性,同時(shí)也增加了開(kāi)發(fā)者的心智負(fù)擔(dān)。是在上線之前多費(fèi)心思寫(xiě)代碼,還是在上線以后忙忙活活查問(wèn)題,這是個(gè) trade off 問(wèn)題。俗話講:"背著抱著,一樣沉".我本人還是傾向于把問(wèn)題控制在上線之前,少折騰用戶。
到此這篇關(guān)于Rust struct 中的生命周期的文章就介紹到這了,更多相關(guān)Rust struct生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust語(yǔ)言中的String和HashMap使用示例詳解
這篇文章主要介紹了Rust語(yǔ)言中的String和HashMap使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Rust數(shù)據(jù)類型之結(jié)構(gòu)體Struct的使用
結(jié)構(gòu)體是Rust中非常強(qiáng)大和靈活的數(shù)據(jù)結(jié)構(gòu),可以用于組織和操作各種類型的數(shù)據(jù),本文就來(lái)介紹一下Rust數(shù)據(jù)類型之結(jié)構(gòu)體Struct的使用,感興趣的可以了解一下2023-12-12使用Rust制作康威生命游戲的實(shí)現(xiàn)代碼
這篇文章主要介紹了使用Rust制作康威生命游戲,初始rust項(xiàng)目,使用wasm的項(xiàng)目模板,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09為什么要使用 Rust 語(yǔ)言、Rust 語(yǔ)言有什么優(yōu)勢(shì)
雖然 Rust 是一種通用的多范式語(yǔ)言,但它的目標(biāo)是 C 和 C++占主導(dǎo)地位的系統(tǒng)編程領(lǐng)域,很多朋友會(huì)問(wèn)rust語(yǔ)言難學(xué)嗎?rust語(yǔ)言可以做什么,今天帶著這些疑問(wèn)通過(guò)本文詳細(xì)介紹下,感興趣的朋友一起看看吧2022-10-10