特征方法中的Rust寿命不匹配 [英] Rust Lifetime mismatch in trait method

查看:45
本文介绍了特征方法中的Rust寿命不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Rust书,并尝试实现允许文本仅在 Draft 状态下添加到博客 Post 的逻辑,例如可以在此处找到(一个建议的练习中.)

I'm working through the Rust book, and trying to implement logic to allow text to only be added to a blog Post if its in the Draft state, as can be found here (one of the suggested exercises).

这个想法是使用结构和特征在Rust中实现状态模式.我只是想将字符串切片传递给 add_text 的默认实现,如果未处于 Draft 状态,则它将返回一个空字符串切片.然后,我将覆盖 Draft 状态的默认实现,并返回为 Draft 状态的文本传递的字符串切片.

The idea is to implement the state pattern in Rust using structs and traits. I simply want to pass a string slice to a default implementation of add_text which returns an empty string slice if not in the Draft state. Then I'll override the default implementation for the Draft state and return the string slice that was passed in for the text in the Draft state.

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, text: &str) {
        let text = self.state.as_ref().unwrap().add_text(text);
        // self.state.as_ref().unwrap().add_content(text)
        self.content.push_str(text);
    }

    //snip

trait State {
    fn request_review(self: Box<Self>) -> Box<dyn State>;
    fn approve(self: Box<Self>) -> Box<dyn State>;
    fn content<'a>(&self, post: &'a Post) -> &'a str {
        ""
    }
    fn reject(self: Box<Self>) -> Box<dyn State>;
    fn add_text(&self, text: &str) -> &str {
        ""
    }
}

struct Draft {}

impl State for Draft {
    fn request_review(self: Box<Self>) -> Box<dyn State> {
        Box::new(PendingReview {})
    }
    fn approve(self: Box<Self>) -> Box<dyn State> {
        self // don't want to approve a draft before review!
    }
    fn reject(self: Box<Self>) -> Box<dyn State> {
        self // reject doesn't do anything on a draft!
    }
    fn add_text(&self, text: &str) -> &str {
        text
    }
}

impl State for Draft add_text 上方的最后一个方法上,我遇到了生命周期不匹配的问题.该消息显示为:

I'm getting a lifetime mismatch on the very last method above add_text inside impl State for Draft. The message reads:

lifetime mismatch

...but data from `text` is returned hererustc(E0623)
lib.rs(67, 30): this parameter and the return type are declared with different lifetimes...
lib.rs(67, 39):
lib.rs(68, 9): ...but data from `text` is returned here

我是Rust的新手,在这种情况下无法获得有效期注释.我尝试了显式的生命周期注释,但无济于事.另外,我知道由于引用之一是& self ,因此所有生存期参数都应自动具有与& self 相同的生存期(我认为吗?).

I'm new to Rust and can't get the lifetime annotations right in this case. I tried explicit lifetime annotations but it didn't help. Also, I know that since one of the references is &self all lifetime parameters should have the same lifetime as &self automatically (I think?).

有人可以启发我来编译此代码吗?对于将来使用这本书的人来说,它也可能有用.

Can someone enlighten me on getting this code to compile? It also may be useful to those using the book in the future.

推荐答案

您被

输入位置的每个有效寿命成为一个独特的寿命参数.

Each elided lifetime in input position becomes a distinct lifetime parameter.

如果仅存在一个输入生命周期位置(是否消除),则将该生命周期分配给所有消除的输出生命周期.

If there is exactly one input lifetime position (elided or not), that lifetime is assigned to all elided output lifetimes.

如果存在多个输入生命周期位置,但是其中一个是& self & mut self ,则 self 的生​​命周期分配给所有淘汰的输出寿命.

If there are multiple input lifetime positions, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.

否则,缩短输出寿命是错误的.

Otherwise, it is an error to elide an output lifetime.

在您的代码中 add_text(& self,text:& str)->& str ,返回的& str & self 提取了寿命,但实际上它是第二个参数.好像是不匹配的:

In your code fn add_text(&self, text: &str) -> &str, the returned &str picks up the elided lifetime from &self, but then it is actually the second parameter. A mismatch as if it were:

fn add_text<'a, 'b>(&'a self, text: &'b str) -> &'a str {
    text
}

诀窍是在此处明确显示生命周期:

The trick is to make lifetime explicit here:

trait State {
    fn add_text<'a>(&'a self, text: &'a str) -> &'a str;
}

impl State for Draft {
    fn add_text<'a>(&'a self, text: &'a str) -> &'a str {
        text
    }
}

如果您想要更通用的版本:

If you want a slightly more general version:

trait State {
    fn add_text<'a, 'b: 'a>(&'a self, text: &'b str) -> &'a str;
}

impl State for Draft {
    fn add_text<'a, 'b: 'a>(&'a self, text: &'b str) -> &'a str {
        text
    }
}

在这里说,只要 text 胜过& self ,一切都很好.您可以决定是否值得增加额外的通用寿命.

Here it says as long as text outlives &self all is good. You decide if the extra generic lifetime is worth the trouble.

这篇关于特征方法中的Rust寿命不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆