Struct std::rc::Rc1.0.0[][src]

pub struct Rc<T> where
    T: ?Sized
{ /* fields omitted */ }
Expand description

单线程引用计数指针。Rc 代表引用计数。

有关更多详细信息,请参见 模块级文档

Rc 的固有方法都是关联函数,这意味着您必须以例如 Rc::get_mut(&mut value) 而不是 value.get_mut() 的方式调用它们。 这样可以避免与内部类型 T 的方法发生冲突。

Implementations

创建一个新的 Rc<T>

Examples

use std::rc::Rc;

let five = Rc::new(5);
Run
🔬 This is a nightly-only experimental API. (arc_new_cyclic #75861)

使用对自身的弱引用创建一个新的 Rc<T>。 在此函数返回之前尝试升级弱引用将得到 None 值。

但是,弱引用可以自由克隆并存储以备后用。

Examples

#![feature(arc_new_cyclic)]
#![allow(dead_code)]
use std::rc::{Rc, Weak};

struct Gadget {
    self_weak: Weak<Self>,
    // ... 更多领域
}
impl Gadget {
    pub fn new() -> Rc<Self> {
        Rc::new_cyclic(|self_weak| {
            Gadget { self_weak: self_weak.clone(), /* ... */ }
        })
    }
}
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

创建一个具有未初始化内容的新 Rc

Examples

#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut five = Rc::<u32>::new_uninit();

let five = unsafe {
    // 延迟初始化:
    Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);

    five.assume_init()
};

assert_eq!(*five, 5)
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

创建一个具有未初始化内容的新 Rc,并用 0 字节填充内存。

有关正确和不正确使用此方法的示例,请参见 MaybeUninit::zeroed

Examples

#![feature(new_uninit)]

use std::rc::Rc;

let zero = Rc::<u32>::new_zeroed();
let zero = unsafe { zero.assume_init() };

assert_eq!(*zero, 0)
Run
🔬 This is a nightly-only experimental API. (allocator_api #32838)

创建一个新的 Rc<T>,如果分配失败,则返回错误

Examples

#![feature(allocator_api)]
use std::rc::Rc;

let five = Rc::try_new(5);
Run
🔬 This is a nightly-only experimental API. (allocator_api #32838)

用未初始化的内容构造一个新的 Rc,如果分配失败,则返回错误

Examples

#![feature(allocator_api, new_uninit)]
#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut five = Rc::<u32>::try_new_uninit()?;

let five = unsafe {
    // 延迟初始化:
    Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);

    five.assume_init()
};

assert_eq!(*five, 5);
Run
🔬 This is a nightly-only experimental API. (allocator_api #32838)

创建一个具有未初始化内容的新 Rc,并用 0 字节填充内存,如果分配失败,则返回错误

有关正确和不正确使用此方法的示例,请参见 MaybeUninit::zeroed

Examples

#![feature(allocator_api, new_uninit)]

use std::rc::Rc;

let zero = Rc::<u32>::try_new_zeroed()?;
let zero = unsafe { zero.assume_init() };

assert_eq!(*zero, 0);
Run

创建一个新的 Pin<Rc<T>>。 如果 T 未实现 Unpin,则 value 将被固定在内存中并且无法移动。

如果 Rc 正好有一个强引用,则返回内部值。

否则,返回的 Err 将与传入的 Rc 相同。

即使存在突出的弱引用,此操作也将成功。

Examples

use std::rc::Rc;

let x = Rc::new(3);
assert_eq!(Rc::try_unwrap(x), Ok(3));

let x = Rc::new(4);
let _y = Rc::clone(&x);
assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

创建一个新的带有未初始化内容的引用计数的切片。

Examples

#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut values = Rc::<[u32]>::new_uninit_slice(3);

let values = unsafe {
    // 延迟初始化:
    Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
    Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
    Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);

    values.assume_init()
};

assert_eq!(*values, [1, 2, 3])
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

用未初始化的内容创建一个新的带有引用计数的切片,内存中填充 0 字节。

有关正确和不正确使用此方法的示例,请参见 MaybeUninit::zeroed

Examples

#![feature(new_uninit)]

use std::rc::Rc;

let values = Rc::<[u32]>::new_zeroed_slice(3);
let values = unsafe { values.assume_init() };

assert_eq!(*values, [0, 0, 0])
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

转换为 Rc<T>

Safety

MaybeUninit::assume_init 一样,由调用方负责确保内部值确实处于初始化状态。

在内容尚未完全初始化时调用此方法会立即导致未定义的行为。

Examples

#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut five = Rc::<u32>::new_uninit();

let five = unsafe {
    // 延迟初始化:
    Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);

    five.assume_init()
};

assert_eq!(*five, 5)
Run
🔬 This is a nightly-only experimental API. (new_uninit #63291)

转换为 Rc<[T]>

Safety

MaybeUninit::assume_init 一样,由调用方负责确保内部值确实处于初始化状态。

在内容尚未完全初始化时调用此方法会立即导致未定义的行为。

Examples

#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut values = Rc::<[u32]>::new_uninit_slice(3);

let values = unsafe {
    // 延迟初始化:
    Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
    Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
    Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);

    values.assume_init()
};

assert_eq!(*values, [1, 2, 3])
Run

消耗 Rc,返回包装的指针。

为避免内存泄漏,必须使用 Rc::from_raw 将指针转换回 Rc

Examples

use std::rc::Rc;

let x = Rc::new("hello".to_owned());
let x_ptr = Rc::into_raw(x);
assert_eq!(unsafe { &*x_ptr }, "hello");
Run

为数据提供裸指针。

计数不会受到任何影响,并且不会消耗 Rc。 只要 Rc 中存在大量计数,指针就有效。

Examples

use std::rc::Rc;

let x = Rc::new("hello".to_owned());
let y = Rc::clone(&x);
let x_ptr = Rc::as_ptr(&x);
assert_eq!(x_ptr, Rc::as_ptr(&y));
assert_eq!(unsafe { &*x_ptr }, "hello");
Run

从裸指针构造 Rc<T>

裸指针必须事先由调用返回到 Rc<U>::into_raw,其中 U 的大小和对齐方式必须与 T 相同。 如果 UT,这是很简单的。 请注意,如果 U 不是 T,但是具有相同的大小和对齐方式,则基本上就像对不同类型的引用进行转换一样。 有关在这种情况下适用的限制的更多信息,请参见 mem::transmute

from_raw 的用户必须确保 T 的特定值仅被丢弃一次。

此函数不安全,因为使用不当可能会导致内存不安全,即使从未访问返回的 Rc<T> 也是如此。

Examples

use std::rc::Rc;

let x = Rc::new("hello".to_owned());
let x_ptr = Rc::into_raw(x);

unsafe {
    // 转换回 `Rc` 以防止泄漏。
    let x = Rc::from_raw(x_ptr);
    assert_eq!(&*x, "hello");

    // 进一步调用 `Rc::from_raw(x_ptr)` 将导致内存不安全。
}

// 当 `x` 离开作用域时,内存被释放,所以 `x_ptr` 现在悬空了!
Run

创建一个指向该分配的新 Weak 指针。

Examples

use std::rc::Rc;

let five = Rc::new(5);

let weak_five = Rc::downgrade(&five);
Run

获取指向该分配的 Weak 指针的数量。

Examples

use std::rc::Rc;

let five = Rc::new(5);
let _weak_five = Rc::downgrade(&five);

assert_eq!(1, Rc::weak_count(&five));
Run

获取指向此分配的强 (Rc) 指针的数量。

Examples

use std::rc::Rc;

let five = Rc::new(5);
let _also_five = Rc::clone(&five);

assert_eq!(2, Rc::strong_count(&five));
Run

将与提供的指针关联的 Rc<T> 上的强引用计数增加 1。

Safety

指针必须是通过 Rc::into_raw 获得的,并且关联的 Rc 实例必须是有效的 (即 在此方法的持续时间内,强引用计数必须至少为 1)。

Examples

use std::rc::Rc;

let five = Rc::new(5);

unsafe {
    let ptr = Rc::into_raw(five);
    Rc::increment_strong_count(ptr);

    let five = Rc::from_raw(ptr);
    assert_eq!(2, Rc::strong_count(&five));
}
Run

将与提供的指针关联的 Rc<T> 上的强引用计数减一。

Safety

指针必须是通过 Rc::into_raw 获得的,并且关联的 Rc 实例必须是有效的 (即 调用此方法时,强引用计数必须至少为 1)。 此方法可用于释放最终的 Rc 和后备存储,但不应在最终的 Rc 释放后调用。

Examples

use std::rc::Rc;

let five = Rc::new(5);

unsafe {
    let ptr = Rc::into_raw(five);
    Rc::increment_strong_count(ptr);

    let five = Rc::from_raw(ptr);
    assert_eq!(2, Rc::strong_count(&five));
    Rc::decrement_strong_count(ptr);
    assert_eq!(1, Rc::strong_count(&five));
}
Run

如果没有其他 RcWeak 指向相同分配的指针,则返回给定 Rc 的可变引用。

否则返回 None,因为更改共享值并不安全。

另请参见 make_mut,当存在其他指针时,它将 clone 内部值。

Examples

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());
Run
🔬 This is a nightly-only experimental API. (get_mut_unchecked #63292)

将变量引用返回给定的 Rc,而不进行任何检查。

另请参见 get_mut,它是安全的并且进行适当的检查。

Safety

在返回的借用期间,不得解引用其他指向相同分配的 RcWeak 指针。

如果不存在这样的指针 (例如紧接在 Rc::new 之后),则情况很简单。

Examples

#![feature(get_mut_unchecked)]

use std::rc::Rc;

let mut x = Rc::new(String::new());
unsafe {
    Rc::get_mut_unchecked(&mut x).push_str("foo")
}
assert_eq!(*x, "foo");
Run

如果两个 Rc 指向相同的分配 (类似于 ptr::eq),则返回 true

Examples

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_five));
assert!(!Rc::ptr_eq(&five, &other_five));
Run

对给定的 Rc 进行可变引用。

如果还有其他指向同一分配的 Rc 指针,则 make_mut 会将 clone 的内部值分配给新分配,以确保唯一的所有权。 这也称为写时克隆。

如果没有其他指向该分配的 Rc 指针,则指向该分配的 Weak 指针将被取消关联。

另请参见 get_mut,它将失败而不是克隆。

Examples

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);
Run

Weak 指针将被取消关联:

use std::rc::Rc;

let mut data = Rc::new(75);
let weak = Rc::downgrade(&data);

assert!(75 == *data);
assert!(75 == *weak.upgrade().unwrap());

*Rc::make_mut(&mut data) += 1;

assert!(76 == *data);
assert!(weak.upgrade().is_none());
Run

尝试将 Rc<dyn Any> 转换为具体类型。

Examples

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);
    }
}

let my_string = "Hello World".to_string();
print_if_string(Rc::new(my_string));
print_if_string(Rc::new(0i8));
Run

Trait Implementations

执行转换。

从拥有的值中一成不变地借用。 Read more

克隆 Rc 指针。

这将创建另一个指向相同分配的指针,从而增加了强引用计数。

Examples

use std::rc::Rc;

let five = Rc::new(5);

let _ = Rc::clone(&five);
Run

source 执行复制分配。 Read more

使用给定的格式化程序格式化该值。 Read more

TDefault 值创建一个新的 Rc<T>

Examples

use std::rc::Rc;

let x: Rc<i32> = Default::default();
assert_eq!(*x, 0);
Run

解引用后的结果类型。

解引用值。

使用给定的格式化程序格式化该值。 Read more

丢弃 Rc

这将减少强引用计数。 如果强引用计数达到零,那么唯一的其他引用 (如果有) 是 Weak,因此我们将 drop 作为内部值。

Examples

use std::rc::Rc;

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("dropped!");
    }
}

let foo  = Rc::new(Foo);
let foo2 = Rc::clone(&foo);

drop(foo);    // 不打印任何东西
drop(foo2);   // 打印 "dropped!"
Run

分配一个引用计数的切片,并通过克隆 v 的项来填充它。

Example

let original: &[i32] = &[1, 2, 3];
let shared: Rc<[i32]> = Rc::from(original);
assert_eq!(&[1, 2, 3], &shared[..]);
Run

执行转换。

执行转换。

通过将 Path 数据复制到新的 Rc 缓冲区,将 Path 转换为 Rc

分配一个引用计数的字符串切片并将 v 复制到其中。

Example

let shared: Rc<str> = Rc::from("statue");
assert_eq!("statue", &shared[..]);
Run

将 boxed 对象移动到引用计数的新分配。

Example

let original: Box<i32> = Box::new(1);
let shared: Rc<i32> = Rc::from(original);
assert_eq!(1, *shared);
Run

无需复制或分配即可将 CString 转换为 Rc<CStr>

通过复制其内容,从写时克隆指针创建一个引用计数指针。

Example

let cow: Cow<str> = Cow::Borrowed("eggplant");
let shared: Rc<str> = Rc::from(cow);
assert_eq!("eggplant", &shared[..]);
Run

无需复制或分配即可将 OsString 转换为 Rc<OsStr>

通过将 PathBuf 数据移动到新的 Rc 缓冲区,将 PathBuf 转换为 Rc

分配一个引用计数的字符串切片并将 v 复制到其中。

Example

let original: String = "statue".to_owned();
let shared: Rc<str> = Rc::from(original);
assert_eq!("statue", &shared[..]);
Run

将泛型 T 转换为 Rc<T>

转换在堆上分配,并将 t 从栈移到堆中。

Example

let x = 5;
let rc = Rc::new(5);

assert_eq!(Rc::from(x), rc);
Run

分配一个引用计数的切片,并将 v 的项移入其中。

Example

let original: Box<Vec<i32>> = Box::new(vec![1, 2, 3]);
let shared: Rc<Vec<i32>> = Rc::from(original);
assert_eq!(vec![1, 2, 3], *shared);
Run

获取 Iterator 中的每个元素,并将其收集到 Rc<[T]> 中。

性能特点

一般情况

在一般情况下,首先要收集到 Vec<T> 中来收集到 Rc<[T]> 中。也就是说,编写以下内容时:

let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
Run

这就像我们写的那样:

let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
    .collect::<Vec<_>>() // 第一组分配在此处发生。
    .into(); // `Rc<[T]>` 的第二个分配在此处进行。
Run

这将分配构造 Vec<T> 所需的次数,然后分配一次,以将 Vec<T> 转换为 Rc<[T]>

已知长度的迭代器

当您的 Iterator 实现 TrustedLen 且大小正确时,将为 Rc<[T]> 进行一次分配。例如:

let evens: Rc<[u8]> = (0..10).collect(); // 这里只进行一次分配。
Run

将该值输入给定的 HasherRead more

将这种类型的切片送入给定的 Hasher 中。 Read more

两个 Rc 的比较。

通过调用 cmp() 的内部值来比较两者。

Examples

use std::rc::Rc;
use std::cmp::Ordering;

let five = Rc::new(5);

assert_eq!(Ordering::Less, five.cmp(&Rc::new(6)));
Run

比较并返回两个值中的最大值。 Read more

比较并返回两个值中的最小值。 Read more

将值限制为一定的时间间隔。 Read more

两个 Rc 相等。

即使两个 Rc 的内部值相等,即使它们存储在不同的分配中,它们也相等。

如果 T 还实现了 Eq (暗示相等的自反性),则指向同一分配的两个 `Rc’ 始终相等。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five == Rc::new(5));
Run

两个 Rc 的不等式。

如果两个 Rc 的内部值不相等,则它们是不相等的。

如果 T 还实现了 Eq (暗示相等性的反射性),则指向同一分配的两个 Rc 永远不会相等。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five != Rc::new(6));
Run

两个 Rc 的部分比较。

通过调用 partial_cmp() 的内部值来比较两者。

Examples

use std::rc::Rc;
use std::cmp::Ordering;

let five = Rc::new(5);

assert_eq!(Some(Ordering::Less), five.partial_cmp(&Rc::new(6)));
Run

小于两个 Rc 的比较。

通过调用 < 的内部值来比较两者。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five < Rc::new(6));
Run

两个 Rc 的小于或等于比较。

通过调用 <= 的内部值来比较两者。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five <= Rc::new(5));
Run

大于两个 Rc 的比较。

通过调用 > 的内部值来比较两者。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five > Rc::new(4));
Run

两个 Rc 的大于或等于比较。

通过调用 >= 的内部值来比较两者。

Examples

use std::rc::Rc;

let five = Rc::new(5);

assert!(five >= Rc::new(5));
Run

使用给定的格式化程序格式化该值。

发生转换错误时返回的类型。

执行转换。

Auto Trait Implementations

Blanket Implementations

获取 selfTypeIdRead more

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

执行转换。

执行转换。

执行转换。

获得所有权后的结果类型。

通常通过克隆从借用数据中创建拥有的数据。 Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into #41263)

recently added

使用借来的数据来替换拥有的数据,通常是通过克隆。 Read more

将给定值转换为 StringRead more

发生转换错误时返回的类型。

执行转换。

发生转换错误时返回的类型。

执行转换。