gpt4 book ai didi

reference - 用于处理对缓冲区的引用的惯用 Rust 方法

转载 作者:行者123 更新时间:2023-11-29 08:23:42 25 4
gpt4 key购买 nike

我希望能够构造包含对可变缓冲区对象的不可变引用的对象。以下代码不起作用,但说明了我的用例,是否有惯用的 Rust 方法来处理这个问题?

#[derive(Debug)]
struct Parser<'a> {
buffer: &'a String
}

fn main() {
let mut source = String::from("Peter");
let buffer = &source;
let parser = Parser { buffer };

// How can I legally change source?
source.push_str(" Pan");

println!("{:?}", parser);
}

最佳答案

rust borrow checker 的黄金法则是:一次只有一个写入者或多个读取者可以访问一个资源。这确保了算法可以安全地在多线程中运行。

你在这里违反了这条规则:

#[derive(Debug)]
struct Parser<'a> {
buffer: &'a String
}

fn main() {
// mutable access begins here
let mut source = String::from("Peter");
// immutable access begins here
let buffer = &source;
let parser = Parser { buffer };

source.push_str(" Pan");

println!("{:?}", parser);
// Both immutable and mutable access end here
}

如果您确定您的程序不会同时以可变和不可变方式主动访问资源,您可以通过将资源包装在 RefCell 中,将检查从编译时转移到运行时:

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug)]
struct Parser {
buffer: Rc<RefCell<String>>
}

fn main() {
let source = Rc::new(RefCell::new(String::from("Peter")));
let parser = Parser { buffer: source.clone() };

source.borrow_mut().push_str(" Pan");

println!("{:?}", parser);
}

如果你计划在线程周围传递你的资源,你可以使用 RwLock 来阻塞线程直到资源可用:

use std::sync::{RwLock, Arc};

#[derive(Debug)]
struct Parser {
buffer: Arc<RwLock<String>>
}

fn main() {
let source = Arc::new(RwLock::new(String::from("Peter")));
let parser = Parser { buffer: source.clone() };

source.write().unwrap().push_str(" Pan");

println!("{:?}", parser);
}

另一方面,您应该更喜欢 &str 而不是 &String

关于reference - 用于处理对缓冲区的引用的惯用 Rust 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45796365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com