gpt4 book ai didi

rust - 面向对象的 Rust(Rust 书第 17 章博客)

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

我想在 options of going further for creating the blog from The Rust Programming Language 上实现最后一个要点:

Allow users to add text content only when a post is in the Draft state. Hint: have the state object responsible for what might change about the content but not responsible for modifying the Post.

我想实现 add_text 方法,该方法将具有默认实现,该实现在 State 特征中不执行任何操作,但会将字符串推送到 post.content 如果状态为 Draft:

pub struct Post {
state: Option<Box<dyn State>>,
content: String,
}

impl Post {
pub fn new() -> Post {
Post {
state: Some(Box::new(Draft {})),
content: String::new(),
}
}

pub fn add_text(&mut self, string: &str) {
self.state.as_ref().unwrap().add_text(&mut self, string)
}

pub fn content(&self) -> &str {
self.state.as_ref().unwrap().content(&self)
}
}

trait State {
fn content<'a>(&self, post: &'a Post) -> &'a str {
""
}
fn add_text<'a>(&self, post: &'a mut Post, string: &str) {
"";
}
}

impl State for Draft {
fn add_text<'a>(&self, post: &'a mut Post, string: &str) {
&mut post.content.push_str(string);
}
}

我的问题是围绕这行 Post::add_text

self.state.as_ref().unwrap().add_text(&mut self, string)

我得到一个 cannot borrow as mutable try removing &mut.

但是:

self.state.as_ref().unwrap().add_text(self, string)

给我“不能将 *self 借用为可变的,因为它也被借用为不可变的”。

有人可以帮我解决这个问题吗?我不确定我是否以正确的方式处理这件事。

最佳答案

问题是 statePost 的成员。如果你借用 state 那么你不能同时借用 self (即 Post),这是正确的。考虑一下如果您的 Draft::add_text() 函数分配给接收到的 post.state 会发生什么:

impl State for Draft {
fn add_text<'a>(&self, post: &'a mut Post, string: &str) {
post.state = None; //killed self!
}
}

这将使 self 在此函数运行时消失!那将是非常不安全的。

这种使用模式在 Rust 中是不允许的,但是你有几个可用的解决方法。在我看来,最好的办法是将要变异的数据分离为另一种类型:

pub struct PostData {
content: String,
}
pub struct Post {
state: Option<Box<dyn State>>,
data: PostData,
}
trait State {
fn add_text<'a>(&self, post: &'a mut PostData, string: &str) {
"";
}
//...
}
impl Post {
pub fn add_text(&mut self, string: &str) {
self.state.as_ref().unwrap().add_text(&mut self.data, string)
}
}

之所以可行,是因为您借用了分开的 self 片段,一方面是 self.state,另一方面是 self.data .

另一个简单的解决方法是从 Post 中删除状态并稍后重新添加它:

impl Post {
pub fn add_text(&mut self, string: &str) {
let state = self.state.take();
state.as_ref().unwrap().add_text(&mut self, string);
assert!(self.state.is_none());
self.state = Some(state);
}
}

就我个人而言,我觉得这个解决方案有点hacky

关于rust - 面向对象的 Rust(Rust 书第 17 章博客),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57413949/

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