如何与 Rc 共享字符串的一部分?

Yoh*_*hei 3 string reference-counting slice rust

我想创建一些对strwith Rc, without cloning 的引用str

fn main() {
    let s = Rc::<str>::from("foo");
    let t = Rc::clone(&s); // Creating a new pointer to the same address is easy
    let u = Rc::clone(&s[1..2]); // But how can I create a new pointer to a part of `s`?

    let w = Rc::<str>::from(&s[0..2]); // This seems to clone str
    assert_ne!(&w as *const _, &s as *const _);
}
Run Code Online (Sandbox Code Playgroud)

操场

我怎样才能做到这一点?

Kev*_*eid 6

虽然原则上这是可能的,但标准库Rc不支持您尝试创建的情况:对引用计数内存的一部分的计数引用。

\n

但是,我们可以使用一个相当简单的包装器来获得字符串的效果,Rc该包装器会记住子字符串范围:

\n
use std::ops::{Deref, Range};\nuse std::rc::Rc;\n\n#[derive(Clone, Debug, Eq, Hash, PartialEq)]\npub struct RcSubstr {\n    string: Rc<str>,\n    span: Range<usize>,\n}\n\nimpl RcSubstr {\n    fn new(string: Rc<str>) -> Self {\n        let span = 0..string.len();\n        Self { string, span }\n    }\n    fn substr(&self, span: Range<usize>) -> Self {\n        // A full implementation would also have bounds checks to ensure\n        // the requested range is not larger than the current substring\n        Self {\n            string: Rc::clone(&self.string),\n            span: (self.span.start + span.start)..(self.span.start + span.end)\n        }\n    }\n}\n\nimpl Deref for RcSubstr {\n    type Target = str;\n    fn deref(&self) -> &str {\n        &self.string[self.span.clone()]\n    }\n}\n\nfn main() {\n    let s = RcSubstr::new(Rc::<str>::from("foo"));\n    let u = s.substr(1..2);\n    \n    // We need to deref to print the string rather than the wrapper struct.\n    // A full implementation would `impl Debug` and `impl Display` to produce\n    // the expected substring.\n    println!("{}", &*u);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这里缺少很多便利,例如DisplayDebugAsRefBorrowFromInto\xe2\x80\x94 的适当实现,我只提供了足够的代码来说明它是如何工作的。Rc<str>一旦补充了适当的特征实现,这应该和(有一种边缘情况,即它不能传递给想要Rc<str> 特定存储的库类型)一样可用。

\n

该板条箱arcstr声称提供了这个基本想法的完成版本,但我尚未使用或研究过它,因此无法保证其质量。

\n

该板条箱owning_ref提供了一种保存对 Rc 或其他智能指针部分的引用的方法,但有人担心它的健全性,而且我不完全理解它适用于哪些情况(问题搜索目前有 3 个未解决的问题)。

\n