假设我想编写一个类型来构建一个相当大的字符串(比如 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
来防止调用代码中的任何进一步引用,但可变引用立即超出范围。
经过更多实验,看起来
unwrap
应该写成
pub fn unwrap(self: Self) -> String {
self.buffer.take()
}
通过此实现,
unwrap
获得其自身的所有权,并在 unwrap
函数返回时放弃自身。 take
的 RefCell
函数执行类似的操作,将内容移出 RefCell 并将所有权返回给 unwrap
的调用者
我会做类似的事情
pub fn build(self) -> String {
self.buffer.take()
}
self
的值(不是参考)会消耗构建器。