第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何在不破壞封裝的情況下返回對(duì)RefCell內(nèi)部?jī)?nèi)容的引用?

如何在不破壞封裝的情況下返回對(duì)RefCell內(nèi)部?jī)?nèi)容的引用?

Git
慕斯709654 2019-11-19 15:14:33
我有一個(gè)具有內(nèi)部可變性的結(jié)構(gòu)。use std::cell::RefCell;struct MutableInterior {    hide_me: i32,    vec: Vec<i32>,}struct Foo {    //although not used in this particular snippet,    //the motivating problem uses interior mutability    //via RefCell.    interior: RefCell<MutableInterior>,}impl Foo {    pub fn get_items(&self) -> &Vec<i32> {        &self.interior.borrow().vec    }}fn main() {    let f = Foo {        interior: RefCell::new(MutableInterior {            vec: Vec::new(),            hide_me: 2,        }),    };    let borrowed_f = &f;    let items = borrowed_f.get_items();}產(chǎn)生錯(cuò)誤:error[E0597]: borrowed value does not live long enough  --> src/main.rs:16:10   |16 |         &self.interior.borrow().vec   |          ^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough17 |     }   |     - temporary value only lives until here   |note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 15:5...  --> src/main.rs:15:5   |15 | /     pub fn get_items(&self) -> &Vec<i32> {16 | |         &self.interior.borrow().vec17 | |     }   | |_____^問(wèn)題是我無(wú)法在該函數(shù)上Foo返回借用vec,因?yàn)榻栌胿ec僅在的有效期內(nèi)有效Ref,但Ref立即超出范圍。我認(rèn)為Ref必須堅(jiān)持,因?yàn)椋篟efCell<T>使用Rust的生命周期來(lái)實(shí)現(xiàn)“動(dòng)態(tài)借用”,這一過(guò)程使人們可以要求對(duì)內(nèi)部?jī)r(jià)值進(jìn)行臨時(shí),排他,可變的訪問(wèn)。RefCell<T>s的借記是在“運(yùn)行時(shí)”進(jìn)行跟蹤的,這與Rust的本機(jī)引用類型不同,后者在編譯時(shí)是完全靜態(tài)跟蹤的。由于RefCell<T>借貸是動(dòng)態(tài)的,因此可以嘗試借入已經(jīng)可變借貸的值;當(dāng)這種情況發(fā)生時(shí),將導(dǎo)致任務(wù)恐慌?,F(xiàn)在,我可以改寫(xiě)這樣的函數(shù)來(lái)返回整個(gè)內(nèi)部:pub fn get_mutable_interior(&self) -> std::cell::Ref<MutableInterior>;但是,這可能會(huì)將字段(MutableInterior.hide_me在此示例中)暴露為真正的私有實(shí)現(xiàn)細(xì)節(jié)Foo。理想情況下,我只想公開(kāi)vec自身,可能需要配備警衛(wèi)來(lái)實(shí)現(xiàn)動(dòng)態(tài)借用行為。然后,呼叫者不必了解hide_me。
查看完整描述

3 回答

?
有只小跳蛙

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超8個(gè)贊

您可以創(chuàng)建一個(gè)與所Ref<'a,T>返回的后衛(wèi)類似的新結(jié)構(gòu)RefCell::borrow(),以對(duì)其進(jìn)行包裝Ref并避免其超出范圍,例如:


use std::cell::Ref;


struct FooGuard<'a> {

    guard: Ref<'a, MutableInterior>,

}

然后,您可以Deref為其實(shí)現(xiàn)特征,以便可以像使用它一樣使用它&Vec<i32>:


use std::ops::Deref;


impl<'b> Deref for FooGuard<'b> {

    type Target = Vec<i32>;


    fn deref(&self) -> &Vec<i32> {

        &self.guard.vec

    }

}

之后,更新您的get_items()方法以返回FooGuard實(shí)例:


impl Foo {

    pub fn get_items(&self) -> FooGuard {

        FooGuard {

            guard: self.interior.borrow(),

        }

    }

}

并Deref做魔術(shù):


fn main() {

    let f = Foo {

        interior: RefCell::new(MutableInterior {

            vec: Vec::new(),

            hide_me: 2,

        }),

    };

    let borrowed_f = &f;

    let items = borrowed_f.get_items();

    let v: &Vec<i32> = &items;

}


查看完整回答
反對(duì) 回復(fù) 2019-11-19
?
函數(shù)式編程

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊

您可以使用Ref::map(從Rust 1.8開(kāi)始)而不是創(chuàng)建全新的類型。這與Levans的現(xiàn)有答案具有相同的結(jié)果:


use std::cell::Ref;


impl Foo {

    pub fn get_items(&self) -> Ref<'_, Vec<i32>> {

        Ref::map(self.interior.borrow(), |mi| &mi.vec)

    }

}

您還可以使用新功能,例如從API中impl Trait隱藏Ref:


use std::cell::Ref;

use std::ops::Deref;


impl Foo {

    pub fn get_items(&self) -> impl Deref<Target = Vec<i32>> + '_ {

        Ref::map(self.interior.borrow(), |mi| &mi.vec)

    }

}


查看完整回答
反對(duì) 回復(fù) 2019-11-19
?
侃侃爾雅

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊

你可以包裝Vec在Rc。


use std::cell::RefCell;

use std::rc::Rc;


struct MutableInterior {

    hide_me: i32,

    vec: Rc<Vec<i32>>,

}

struct Foo {

    interior: RefCell<MutableInterior>,

}


impl Foo {

    pub fn get_items(&self) -> Rc<Vec<i32>> {

        self.interior.borrow().vec.clone() // clones the Rc, not the Vec

    }

}


fn main() {

    let f = Foo {

        interior: RefCell::new(MutableInterior {

            vec: Rc::new(Vec::new()),

            hide_me: 2,

        }),

    };

    let borrowed_f = &f;

    let items = borrowed_f.get_items();

}

當(dāng)您需要對(duì)進(jìn)行突變時(shí)Vec,可使用Rc::make_mut獲取對(duì)的可變引用Vec。如果還有其他的Rc小號(hào)指的是Vec,make_mut將分離的Rc與其他RcS,克隆Vec和更新本身指的是新的Vec,然后給你一個(gè)可變的引用。這樣可以確保其他Rcs中的值不會(huì)突然改變(因?yàn)镽c它本身不提供內(nèi)部可變性)。

查看完整回答
反對(duì) 回復(fù) 2019-11-19
  • 3 回答
  • 0 關(guān)注
  • 682 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)