pub struct Weak<T: ?Sized> { /* private fields */ }
Expand description
Weak
是 Rc
的一个版本,它持有对托管分配的非所有权引用。
通过在 Weak
指针上调用 upgrade
来访问分配,它返回一个 Option<Rc<T>>
。
由于 Weak
引用不计入所有权,因此它不会防止存储在分配中的值被丢弃,并且 Weak
本身不保证该值仍然存在。
因此,当 upgrade
时,它可能返回 None
。
但是请注意,Weak
引用 确实 会阻止分配本身 (后备存储) 被释放。
Weak
指针可用于保持对 Rc
管理的分配的临时引用,而又不会阻止其内部值被丢弃。
它也用于防止 Rc
指针之间的循环引用,因为相互拥有引用将永远不允许丢弃 Rc
。
例如,一棵树可以具有从父节点到子节点的强 Rc
指针,以及从子节点到其父节点的 Weak
指针。
获取 Weak
指针的典型方法是调用 Rc::downgrade
。
Implementations§
source§impl<T: ?Sized> Weak<T>
impl<T: ?Sized> Weak<T>
1.45.0 · sourcepub fn as_ptr(&self) -> *const T
pub fn as_ptr(&self) -> *const T
返回对此 Weak<T>
指向的对象 T
的裸指针。
该指针仅在有一些强引用时才有效。
指针可能是悬垂的,未对齐的,甚至是 null
。
Examples
use std::rc::Rc;
use std::ptr;
let strong = Rc::new("hello".to_owned());
let weak = Rc::downgrade(&strong);
// 两者都指向同一个对象
assert!(ptr::eq(&*strong, weak.as_ptr()));
// 这里的强项使它保持活动状态,因此我们仍然可以访问该对象。
assert_eq!("hello", unsafe { &*weak.as_ptr() });
drop(strong);
// 但是没有更多了。
// 我们可以执行 weak.as_ptr(),但是访问指针将导致未定义的行为。
// assert_eq!("hello", unsafe { &*weak.as_ptr() });
Run1.45.0 · sourcepub fn into_raw(self) -> *const T
pub fn into_raw(self) -> *const T
消耗 Weak<T>
并将其转换为裸指针。
这会将弱指针转换为裸指针,同时仍保留一个弱引用的所有权 (此操作不会修改弱引用计数)。
可以将其转换回带有 from_raw
的 Weak<T>
。
与 as_ptr
一样,访问指针目标的限制也适用。
Examples
use std::rc::{Rc, Weak};
let strong = Rc::new("hello".to_owned());
let weak = Rc::downgrade(&strong);
let raw = weak.into_raw();
assert_eq!(1, Rc::weak_count(&strong));
assert_eq!("hello", unsafe { &*raw });
drop(unsafe { Weak::from_raw(raw) });
assert_eq!(0, Rc::weak_count(&strong));
Run1.45.0 · sourcepub unsafe fn from_raw(ptr: *const T) -> Self
pub unsafe fn from_raw(ptr: *const T) -> Self
将先前由 into_raw
创建的裸指针转换回 Weak<T>
。
这可以用于安全地获得强引用 (稍后调用 upgrade
) 或通过丢弃 Weak<T>
来分配弱引用计数。
它拥有一个弱引用的所有权 (由 new
创建的指针除外,因为它们不拥有任何东西; 该方法仍适用于它们)。
Safety
指针必须起源于 into_raw
,并且仍然必须拥有其潜在的弱引用。
调用时允许强引用计数为 0。
不过,这需要当前表示为裸指针的弱引用的所有权 (该操作不会修改弱引用计数),因此必须与 into_raw
的先前调用配对。
Examples
use std::rc::{Rc, Weak};
let strong = Rc::new("hello".to_owned());
let raw_1 = Rc::downgrade(&strong).into_raw();
let raw_2 = Rc::downgrade(&strong).into_raw();
assert_eq!(2, Rc::weak_count(&strong));
assert_eq!("hello", &*unsafe { Weak::from_raw(raw_1) }.upgrade().unwrap());
assert_eq!(1, Rc::weak_count(&strong));
drop(strong);
// 减少最后一个弱引用计数。
assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
Runsourcepub fn upgrade(&self) -> Option<Rc<T>>
pub fn upgrade(&self) -> Option<Rc<T>>
尝试将 Weak
指针升级到 Rc
,如果成功,则延迟丢弃内部值。
如果内部值已经被丢弃,则返回 None
。
Examples
use std::rc::Rc;
let five = Rc::new(5);
let weak_five = Rc::downgrade(&five);
let strong_five: Option<Rc<_>> = weak_five.upgrade();
assert!(strong_five.is_some());
// 销毁所有强指针。
drop(strong_five);
drop(five);
assert!(weak_five.upgrade().is_none());
Run1.41.0 · sourcepub fn strong_count(&self) -> usize
pub fn strong_count(&self) -> usize
获取指向该分配的强 (Rc
) 指针的数量。
如果 self
是使用 Weak::new
创建的,这将返回 0.
1.41.0 · sourcepub fn weak_count(&self) -> usize
pub fn weak_count(&self) -> usize
获取指向该分配的 Weak
指针的数量。
如果没有剩余的强指针,它将返回零。
1.39.0 · sourcepub fn ptr_eq(&self, other: &Self) -> bool
pub fn ptr_eq(&self, other: &Self) -> bool
如果两个 Weak
指向与 ptr::eq
类似的相同分配,或者两者都不指向任何分配 (因为它们是使用 Weak::new()
创建的),则返回 true
。
比较 dyn Trait
指针时的注意事项,请参见 that function。
Notes
由于这将比较指针,这意味着 Weak::new()
将彼此相等,即使它们不指向任何分配。
Examples
use std::rc::Rc;
let first_rc = Rc::new(5);
let first = Rc::downgrade(&first_rc);
let second = Rc::downgrade(&first_rc);
assert!(first.ptr_eq(&second));
let third_rc = Rc::new(5);
let third = Rc::downgrade(&third_rc);
assert!(!first.ptr_eq(&third));
Run比较 Weak::new
。
use std::rc::{Rc, Weak};
let first = Weak::new();
let second = Weak::new();
assert!(first.ptr_eq(&second));
let third_rc = Rc::new(());
let third = Rc::downgrade(&third_rc);
assert!(!first.ptr_eq(&third));
RunTrait Implementations§
source§impl<T: ?Sized> Drop for Weak<T>
impl<T: ?Sized> Drop for Weak<T>
source§fn drop(&mut self)
fn drop(&mut self)
丢弃 Weak
指针。
Examples
use std::rc::{Rc, Weak};
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
println!("dropped!");
}
}
let foo = Rc::new(Foo);
let weak_foo = Rc::downgrade(&foo);
let other_weak_foo = Weak::clone(&weak_foo);
drop(weak_foo); // 不打印任何东西
drop(foo); // 打印 "dropped!"
assert!(other_weak_foo.upgrade().is_none());
Run