[英]Method from included Trait implementation not found in scope in Rust
[英]Rust Lifetime mismatch in trait method
我正在阅读 Rust 书,并尝试实现逻辑,以允许仅将文本添加到处于Draft
状态的博客Post
中,可以在此处找到(建议的练习之一)。
这个想法是使用结构和特征在 Rust 中实现状态模式。 我只是想将一个字符串切片传递给add_text
的默认实现,如果不处于Draft
状态, add_text
返回一个空字符串切片。 然后,我将覆盖为默认实现Draft
状态,并返回中传递在文本字符串切片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, 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
上面的最后一个方法上遇到了终生不匹配。 消息内容如下:
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
具有相同的生命周期(我认为?)。
有人可以启发我编译此代码吗? 它也可能对将来使用本书的人有用。
你被终身省略规则绊倒了:
输入位置中的每个省略的生命周期都成为一个不同的生命周期参数。
如果恰好有一个输入生命周期位置(被忽略或不存在),则该生命周期将分配给所有被忽略的输出生命周期。
如果有多个输入终身职位,但其中之一是
&self
或&mut self
,寿命self
被分配到所有消隐输出寿命。否则,省略输出生命周期是错误的。
在您的代码fn add_text(&self, text: &str) -> &str
,返回的&str
从&self
获取省略的生命周期,但它实际上是第二个参数。 不匹配,好像是:
fn add_text<'a, 'b>(&'a self, text: &'b str) -> &'a str {
text
}
诀窍是在这里明确生命周期:
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
}
}
如果你想要一个稍微更通用的版本:
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
长,一切都好。 您决定额外的通用生命周期是否值得麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.