尽管我觉得我清楚地了解了锈的寿命,但我发现我的知识存在差距。 总结一下,为什么此代码无效
struct Token<'a> {
slice: &'a str,
}
struct WrappedToken<'a>(&'a Token<'a>);
trait ToWrappedToken<'a> {
fn to(&'a self) -> WrappedToken<'a>;
}
impl<'a> ToWrappedToken<'a> for Token<'a> {
fn to(&'a self) -> WrappedToken<'a> {
WrappedToken(self)
}
}
fn to_wrap<'a>(token: Token<'a>) -> Box<dyn ToWrappedToken<'a> + 'a> {
Box::new(token)
}
fn main() {
let token = Token {
slice: "It's working well.",
};
let r = to_wrap(token);
r.to();
}
错误:
error[E0597]: `*r` does not live long enough
--> src/main.rs:26:5
|
25 | let r = to_wrap(token);
| - binding `r` declared here
26 | r.to();
| ^ borrowed value does not live long enough
27 | }
| -
| |
| `*r` dropped here while still borrowed
| borrow might be used here, when `r` is dropped and runs the destructor for type `Box<dyn ToWrappedToken<'_>>`
For more information about this error, try `rustc --explain E0597`.
但事实并非如此。据我所知,该代码应该是有效的。如果它无效,那么为什么此代码有效。我刚刚用参考替换了
Box
。仅此而已。
struct Token<'a> {
slice: &'a str,
}
struct WrappedToken<'a>(&'a Token<'a>);
trait ToWrappedToken<'a> {
fn to(&'a self) -> WrappedToken<'a>;
}
impl<'a> ToWrappedToken<'a> for Token<'a> {
fn to(&'a self) -> WrappedToken<'a> {
WrappedToken(self)
}
}
fn to_wrap<'a>(token: &'a Token<'a>) -> &'a dyn ToWrappedToken<'a> {
token
}
fn main() {
let token = Token {
slice: "It's working well.",
};
let r = to_wrap(&token);
r.to();
}
两者都应该在这里有效。
我认为问题出在
&'a Token<'a>
里面的WrappedToken
。这种构造几乎总是一个错误:当您创建这样的值时,基本上您永远借用了该值,因为引用必须与类型一样长。
正如@vallentin上面的评论,在你的代码中你有一个
Token<'static>
,所以当你调用to()
时,你借用它并尝试将其转换为&'static Token<'static>
,但你的变量是本地的main
,并且它无法检查一下。
如果你这样写,一切正常:
struct WrappedToken<'a, 's>(&'s Token<'a>);
trait ToWrappedToken<'a> {
fn to<'s>(&'s self) -> WrappedToken<'a, 's>;
}
impl<'a> ToWrappedToken<'a> for Token<'a> {
fn to<'s>(&'s self) -> WrappedToken<'a, 's> {
WrappedToken(self)
}
}