如何用 Rust 编写高效的构建器?

问题描述 投票:0回答:2

假设我想编写一个类型来构建一个相当大的字符串(比如 html),然后返回它而不复制或克隆该字符串。有没有办法可以实现

unwrap
函数来阻止进一步访问构建器。

例如,这有效:

mod test {
    use std::cell::RefCell;

    struct StringBuilder {
        buffer: RefCell<String>,
    }

    impl StringBuilder {
        pub fn new() -> Self {
            Self { buffer: RefCell::new(String::with_capacity(8000)) }
        }

        pub fn append(self: &Self, s: &str) -> &Self {
            self.buffer.borrow_mut().push_str(s);
            self
        }

        pub fn unwrap(self: &Self) -> String {
            self.buffer.borrow().clone()
        }
    }

    #[test]
    pub fn test() {
        let sb = StringBuilder::new();
        sb.append("a").append("b");
        let s = sb.unwrap();
        println!("{s}");
    }
}

但是它必须克隆

unwrap
中的字符串。我考虑过让
unwrap
采用
&mut Self
而不是
&Self
来防止调用代码中的任何进一步引用,但可变引用立即超出范围。

rust
2个回答
0
投票

经过更多实验,看起来

unwrap
应该写成

pub fn unwrap(self: Self) -> String {
  self.buffer.take()
}

通过此实现,

unwrap
获得其自身的所有权,并在
unwrap
函数返回时放弃自身。
take
RefCell
函数执行类似的操作,将内容移出 RefCell 并将所有权返回给
unwrap

的调用者

0
投票

我会做类似的事情

        pub fn build(self) -> String {
            self.buffer.take()
        }

self
的值(不是参考)会消耗构建器。

© www.soinside.com 2019 - 2024. All rights reserved.