我想创建一个Rc<str>,因为我想减少访问Rc<String>所需的两个指针的间接性.我需要使用Rc,因为我确实拥有共同的所有权.我详细介绍了关于字符串类型的another question个更具体的问题.

Rc has a ?Sized bound:

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

我还听说Rust 1.2将提供适当的支持,用于在Rc中存储未大小的类型,但我不确定这与1.1有何不同.

str case 为例,my naive attempt(也是从String构建的this)出现以下故障:

use std::rc::Rc;

fn main() {
    let a: &str = "test";
    let b: Rc<str> = Rc::new(*a);
    println!("{}", b);
}
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
 --> src/main.rs:5:22
  |
5 |     let b: Rc<str> = Rc::new(*a);
  |                      ^^^^^^^ `str` does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `str`
  = note: required by `<std::rc::Rc<T>>::new`

很明显,为了创建一个Rc<str>,我需要复制整个字符串:RcBox本身就是一个非大小的类型,将字符串本身存储在弱指针和强指针旁边——上面的简单代码甚至没有意义.

有人告诉我,不能实例化这样的类型,而是用大小为TRc<T>来实例化,然后将其强制为非大小的类型.给出的示例是存储一个trait对象:首先创建Rc<ConcreteType>,然后强制为Rc<Trait>.但这也没有意义:thisthis都不起作用(而且你也不能强迫&strStringstr).

推荐答案

从Rust 1.21.0开始,按照RFC 1845的要求,现在可以创建Rc<str>Arc<str>:

use std::rc::Rc;
use std::sync::Arc;

fn main() {
    let a: &str = "hello world";
    let b: Rc<str> = Rc::from(a);
    println!("{}", b);

    // or equivalently:
    let b: Rc<str> = a.into();
    println!("{}", b);

    // we can also do this for Arc,
    let a: &str = "hello world";
    let b: Arc<str> = Arc::from(a);
    println!("{}", b);
}

(Playground)

<Rc as From<&str>><Arc as From<&str>>.

Rust相关问答推荐

使用windows crate Rust 展示windows

什么是谓词的简短和简洁类型

如何对字符串引用的引用向量进行排序,而不是对最外层的引用进行排序?

如果LET;使用布尔表达式链接(&Q);

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

在析构赋值中使用一些现有绑定

无法从流中读取Redis请求

使用极点数据帧时,找不到枚举结果的方法lazy()

如何将映射反序列化为具有与键匹配的字段的定制 struct 的向量?

在Rust中判断编译时是否无法访问

如何初始化选项<;T>;数组Rust 了?

在为第三方 struct 实现第三方特征时避免包装器的任何方法

Boxing 如何将数据从堆栈移动到堆?

borrow 匹配手臂内部的可变

为什么 for_each 在释放模式(cargo run -r)下比 for 循环快得多?

为什么可以在迭代器引用上调用 into_iter?

如何在 C++ 和 Rust 之间共享 pthread 同步原语?

TinyVec 如何与 Vec 大小相同?

带有库+多个二进制文件的Cargo 项目,二进制文件由多个文件组成?

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求