为令人困惑的标题道歉...如果有人想到更好的标题,请编辑这篇文章。
我定义了这样一个特征:
pub trait AsUrlParams
where <Self::I as IntoIterator>::Item: Borrow<(Self::K, Self::V)>,
{
type I: IntoIterator;
type K: AsRef<str>;
type V: AsRef<str>;
fn as_url_params(&self) -> Self::I;
}
为&Vec<(T, U)>
实施它很简单:
impl<'a, T, U> AsUrlParams for &'a Vec<(T, U)>
where T: AsRef<str>,
U: AsRef<str>,
{
type I = Self;
type K = T;
type V = U;
fn as_url_params(&self) -> Self::I {
*self
}
}
但是,在尝试为&mut Vec<(T, U)>
实施该问题时,我遇到了终身问题:
impl<'a, T, U> AsUrlParams for &'a mut Vec<(T, U)>
where T: AsRef<str>,
U: AsRef<str>,
{
type I = Self;
type K = T;
type V = U;
fn as_url_params(&self) -> Self::I {
*self
}
}
这是错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:186:13
|
186 | *self
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 185:43...
--> src/main.rs:185:44
|
185 | fn as_url_params(&self) -> Self::I {
| ____________________________________________^ starting here...
186 | | *self
187 | | }
| |_________^ ...ending here
note: ...so that reference does not outlive borrowed content
--> src/main.rs:186:13
|
186 | *self
| ^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 185:43...
--> src/main.rs:185:44
|
185 | fn as_url_params(&self) -> Self::I {
| ____________________________________________^ starting here...
186 | | *self
187 | | }
| |_________^ ...ending here
note: ...so that types are compatible (expected AsUrlParams, found AsUrlParams)
--> src/main.rs:185:44
|
185 | fn as_url_params(&self) -> Self::I {
| ____________________________________________^ starting here...
186 | | *self
187 | | }
| |_________^ ...ending here
我有两个问题:
&'a mut Vec<(T, U)>
实现此特性?&'a Vec<(T, U)>
发出此错误?从终身的角度来看,它看起来完全一样:&self
的内容是&'a Vec<(T, U)>
,比&self
更长。答案 0 :(得分:2)
让我们比较两个功能签名,desugared。第二个看起来像这样:
fn as_url_params<'b>(self: &'b &'a mut Vec<(T, U)>) -> &'a mut Vec<(T, U)> {
*self
}
在这里,您取消引用self
,为您提供类型&'a mut Vec<(T, U)>
的对象(这是您想要的) - 但它只能在生命周期'b
中生存,因为您从引用中取消引用它一生'b
。由于'b
可能短于'a
,因此这是一个生命周期错误。
那么第一个例子究竟是如何工作的呢?
fn as_url_params<'b>(self: &'b &'a Vec<(T, U)>) -> &'a Vec<(T, U)> {
*self
}
在这种情况下,我们得到一个类型为&'a Vec<(T, U)>
且具有相同借用限制的对象 - 但由于&'a T
实现了Copy
,我们将返回它的新副本。 (它实现Copy
的原因 - 如果中间借用结束并不重要 - 我们知道有一个带有生命期'a
的不可变引用,所以在{{{{}}之前对象不能以任何方式改变1}}已经结束了。)