ref: alloc::rc::Rc - Rusthtml
<!-- toc -->安全
方法函數
<!-- tocstop -->this
std::rc::Rc
是單線程引用計數指針。'RC' 表明 'Reference Counted'。
翻閱 module-level-documentation 查看更多信息Rc
的固有方法都是關聯函數,這意味在使用應該是用相似 Rc::get_mut(&mut value)
而不是 value.get_mut()
的方式調用。這能夠避免與其包含的類型方法衝突。線程
pub fn new(value: T) -> Rc<T>
指針
構造一個 Rc<T>
code
例子htm
use std::rc::Rc; let five = Rc::new(5);
pub fn pin(value: T) -> Pin<Rc<T>>
內存
構建一個新的 Pin<Rc<T>>
。若是 T 沒有實現 Unpin,那麼 value 將會固定在內存中不可移動。資源
pub fn try_unwrap(this: Self) -> Result<T, Self>
若是 Rc 有且只有1個強引用,則返回包含的值,不然返回 Err<T>
。
無論 Rc 有多少弱引用,只要符合上述條件,該函數都將成功。
use std::rc::Rc; fn main() { let x = Rc::new(3); assert_eq!(Rc::try_unwrap(x), Ok(3)); let x = Rc::new(4); let _y = Rc::clone(&x); // 調用 clone 加強強引用 assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); // Rc::try_unwrap(x) 返回 Err(4) }
pub fn into_raw(this: Self) -> *const T
消費 Rc, 返回被包裝的指針。
爲了不內存泄漏,被包裝的指針若是要被從新轉換爲 Rc, 應該使用 Rc::from_raw
例子
use std::rc::Rc; fn main() { let x = Rc::new(4); let x_ptr = Rc::into_raw(x); // x_ptr 爲裸指針 0x142fdcde020 assert_eq!(unsafe { *x_ptr }, 4); }
pub unsafe fn from_raw(ptr: *const T) -> Self
從裸指針中構建一個 Rc。
裸指針必須是從 Rc::into_raw
中返回的裸指針。
這個函數是不安全的,由於不正確使用可能會致使內存問題。例如,在裸指針上二次釋放資源。
use std::rc::Rc; let x = Rc::new(10); let x_ptr = Rc::into_raw(x); unsafe { // 轉換成 Rc 避免內存泄漏 let x = Rc::from_raw(x_ptr); assert_eq!(*x, 10); // 再次調用 `Rc::from_row(x_ptr)` 會致使內存不安全 } // `x` 的內存將會在離開做用域後釋放,因此 `x_ptr` 不是懸吊指針
pub fn downgrade(this: &Self) -> Weak<T>
建立一個被包裹值的弱引用指針
例子
use std::rc::Rc; let five = Rc::new(5); let weak_five = Rc::downgrade(&five);
返回弱引用計數
例子
use std::rc::Rc; let five = Rc::new(5); let _weak_five = Rc::downgrade(&five); assert_eq!(1, Rc::weak_cont(&five));
返回強引用計數
例子
use std::rc::Rc; let five = Rc::new(5); let _also_five = Rc::clone(&five); assert_eq!(2, Rc::strong_count(&five));
若是沒有其餘 Rc 或者 Weak 指針指向內部值,則返回內部值的可變引用,不然返回
None,由於改變共享值是不安全的。
另見 make_mut,這方法會在內部值處於共享狀態時克隆內部值。
例子
use std::rc::Rc; let mut x = Rc::new(3); *Rc::get_mut(&mut x).unwrap() = 4; assert_eq!(*x, 4); let _y = Rc::clone(&x); assert!(Rc::get_mut(&mut x).is_none());
判斷兩個指針是否指向同一個值
例子
use std::rc::Rc; let five = Rc::new(5); let same_five = Rc::clone(&five); let other_five = Rc::new(5); assert!(Rc::ptr_eq(&five, &same_file)); assert!(!Rc::ptr_eq(&five, &other_file));
pub fn make_mut(this: &mut Self) -> &mut T
建立一個 Rc 的可變引用。若是 Rc 還有其餘引用或弱引用,make_mut
將會克隆內部值以保證全部權的惟一性。這也被稱爲寫時克隆。
另見 get_mut,這個方法會失敗而不是克隆
例子
use std::rc::Rc; let mut data = Rc::new(5); *Rc::make_mut(&mut data) += 1; // 不會克隆 let mut other_data = Rc::clone(&data); //此時還未複製 *Rc::make_mut(&mut data) += 1; // 複製內部數據 *Rc::make_mut(&mut data) += 1; // 複製後再次調用原指針將不會觸發克隆 *Rc::make_mut(&mut other_data) *= 2; // 如今 `data` 和 `other_data` 指向不一樣值 assert_eq!(*data, 8); assert_eq!(*other_data, 12);
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>>
嘗試將 Rc<dyn Any> 降級爲具體值
例子
use std::any::Any; use std::rc::Rc; fn print_if_string(value: Rc<dyn Any>) { if let Ok(string) = value.downcast::<String>() { println!("String ({}): {}", string.len(), string); } } fn main() { let my_string = "Hello World".to_string(); print_if_string(Rc::new(my_string)); print_if_string(Rc::new(0i8)); // 不會打印 }