gpt4 book ai didi

rust - 如何将可变的自引用传递给特征方法?

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

在处理 OOP-Chapter 时在 Rust 书(第 2 版)中,我承担了为以下结构实现方法 add_text 的可选任务

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

有 3 个结构体实现了 State 特性,但只有 Draft 结构体应该真正做一些事情。我按如下方式实现了这一点

trait State {
// snip
fn add_text(&self, post: &mut Post, text: &str) { }
}


struct Draft { }

impl State for Draft {
// snip
fn add_text(&self, post: &mut Post, text: &str) {
post.content.push_str(text);
}
}

我的问题是,为了从我的 post 结构中获取 State 来调用 add_text 方法,我不可变地借用了 self(在 Post) 并且不能传递对 State 特性的 add_text 方法的可变引用:

impl Post {
// snip

pub fn add_text(&mut self, text: &str){
let state = self.state.as_ref().unwrap(); // This immutably borrows self
state.add_text(self, text); // so that this mutable borrow is no longer possible
}
}

我该如何应对这种困境?我绝对需要对 Post 的可变引用,否则我无法更改其文本。另一方面,我需要先获取 State,否则我什至无法调用该方法。

解决此问题的一种方法是将 add_text 更改为 get_text_to_add,这不需要 Post 的可变性,但我会我想确保我没有监督解决此问题的任何选项。

最佳答案

对于结构,Rust 足够聪明,能够进行不相交的借用,因此您无需传递对整个 Post 结构的可变引用,只需传递其中需要修改的部分(在这种情况下是内容)。

trait State {
// snip

// Modify the method on the add_text trait so that it
// takes a mutable reference to String
fn add_text(&self, content: &mut String, text: &str) { }
}

struct Draft { }

impl State for Draft {
// snip

// Update the implementation of State for Draft so that it
// matches the new signature
fn add_text(&self, content: &mut String, text: &str) {
content.push_str(text);
}
}

impl Post {
// snip

pub fn add_text(&mut self, text: &str){
let state = self.state.as_ref().unwrap();

// Now when you call add_text you don't require a mutable
// reference to self, just to self.content and so the
// borrow checker is happy
state.add_text(&mut self.content, text);
}
}

这应该可行,但感觉有点勉强,(因为 EvilTak 指出 Draft::add_text 中对 self 的引用是多余的)。我想这是练习的一部分;虽然可以在 Rust 中实现 OOP 的某些模式,但有更好的方法来对问题建模。

关于rust - 如何将可变的自引用传递给特征方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48954007/

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