繁体   English   中英

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

[英]How to pass a mutable self reference on to a trait method?

在完成Rust书的OOP-Chapter (第2版)的过程中,我接受了可选任务来实现以下struct的方法add_text

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

有三个结构实现了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方法,我add_text借用self (在Post )并且不能传递对State trait的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实现某些模式,但有更好的方法可以对问题进行建模。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM