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编译