Rc<T> 是引用計數指針,能夠使用clone
使得指針所指向的數據具備多個全部者。windows
enum List { Cons(i32, Rc<List>), Nil, } use List::{Cons, Nil}; use std::rc::Rc; fn main() { let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); let b = Cons(3, Rc::clone(&a)); let c = Cons(4, Rc::clone(&a)); }
須要注意的是,Rc<T>指針的數據是不可變的3d
RefCell<T>
指針能夠繞過編譯期借用檢查,普通指針和引用同一時間只能有一個可變引用或者多個不可變引用。而RefCell<T>
把這個檢查推遲到了運行時。若是有引用違反了借用原則,程序會panic!指針
use std::cell::RefCell; struct S{ data:i32 } fn main() { let s = RefCell::new(S{data:3}); s.borrow_mut().data=5; println!("{}",s.borrow().data); }
經過&self.borrow()
得到一個不可變借用,&self.borrrow_mut()
得到一個可變借用。code
use std::cell::RefCell; struct S{ data:i32 } fn main() { let s = RefCell::new(S{data:3}); let s1=s.borrow_mut(); let s2 = s.borrow_mut(); }
s有兩個可變引用,這很明顯違反了引用借用原則。因此運行後會獲得一個panic。it
thread 'main' panicked at 'already borrowed: BorrowMutError', src\libcore\result.rs:997:5 stack backtrace: 0: std::sys_common::backtrace::_print at src\libstd\sys\windows\backtrace/mod.rs:95 at src\libstd\sys\windows\backtrace/mod.rs:82 at src\libstd\sys_common/backtrace.rs:71 1: std::panicking::default_hook::{{closure}} at src\libstd\sys_common/backtrace.rs:59 at src\libstd/panicking.rs:197 2: std::panicking::default_hook at src\libstd/panicking.rs:211 3: std::panicking::rust_panic_with_hook at src\libstd/panicking.rs:474 4: std::panicking::continue_panic_fmt at src\libstd/panicking.rs:381 5: rust_begin_unwind at src\libstd/panicking.rs:308 6: core::panicking::panic_fmt at src\libcore/panicking.rs:85 7: core::result::unwrap_failed at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/macros.rs:18 8: core::result::Result<T,E>::expect at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/result.rs:825 9: core::cell::RefCell<T>::borrow_mut at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/cell.rs:873 10: untitled::main at src/main.rs:9 11: std::rt::lang_start::{{closure}} at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libstd/rt.rs:64 12: std::panicking::try::do_call at src\libstd/rt.rs:49 at src\libstd/panicking.rs:293 13: _rust_maybe_catch_panic at src\libpanic_unwind/lib.rs:87 14: std::rt::lang_start_internal at src\libstd/panicking.rs:272 at src\libstd/panic.rs:388 at src\libstd/rt.rs:48 15: std::rt::lang_start at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libstd/rt.rs:64 16: main 17: _tmainCRTStartup 18: mainCRTStartup 19: unit_addrs_search 20: unit_addrs_search
use std::cell::RefCell; use std::rc::Rc; struct S{ data:i32 } fn main() { let s = Rc::new( RefCell::new(S{data:3})); let s1 = Rc::clone(&s); s1.borrow_mut().data=43; println!("{}",RefCell::borrow(&s).data); }
輸出43編譯