特征方法中的 Rust 生命周期不匹配
Rust Lifetime mismatch in trait method
我正在研究 Rust 书,并尝试实现逻辑以允许仅将文本添加到博客 Post
如果其处于 Draft
状态,可以找到 here(建议的练习之一)。
想法是使用结构和特征在 Rust 中实现状态模式。我只是想将一个字符串切片传递给 add_text
的默认实现,如果不处于 Draft
状态,则 return 是一个空字符串切片。然后我将覆盖 Draft
状态的默认实现和 return 为 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
相同的生命周期(我认为?)。
有人可以启发我编译这段代码吗?也可能对以后使用本书的人有用。
你被lifetime elision rules绊倒了:
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.
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.
在您的代码 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
都好。您决定额外的通用生命周期是否值得。
我正在研究 Rust 书,并尝试实现逻辑以允许仅将文本添加到博客 Post
如果其处于 Draft
状态,可以找到 here(建议的练习之一)。
想法是使用结构和特征在 Rust 中实现状态模式。我只是想将一个字符串切片传递给 add_text
的默认实现,如果不处于 Draft
状态,则 return 是一个空字符串切片。然后我将覆盖 Draft
状态的默认实现和 return 为 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
相同的生命周期(我认为?)。
有人可以启发我编译这段代码吗?也可能对以后使用本书的人有用。
你被lifetime elision rules绊倒了:
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.
If there are multiple input lifetime positions, but one of them is
&self
or&mut self
, the lifetime ofself
is assigned to all elided output lifetimes.Otherwise, it is an error to elide an output lifetime.
在您的代码 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
都好。您决定额外的通用生命周期是否值得。