我有一个将某些功能包装在切片上的结构:
use std::fmt::Debug;
struct SliceWrapper<'a, T: Debug + Copy + 'a> {
slice: &'a [T],
pos: usize,
}
我想为支持From
的每个元素实现AsRef<T: Debug + Copy + 'a>
特质,像这样:
impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
fn from(slice: R) -> Self {
Self {
slice: slice.as_ref(),
pos: 0,
}
}
}
我得到了错误:
error[E0597]: `slice` does not live long enough
--> src/lib.rs:11:20
|
11 | slice: slice.as_ref(),
| ^^^^^ borrowed value does not live long enough
...
14 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 8:6...
--> src/lib.rs:8:6
|
8 | impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
| ^^
我不明白这一点,因为我说R
(slice
)的寿命必须与我的SliceWrapper
一样长,而据我了解,AsRef<_>
从self
(slice
)继承生命周期...
答案 0 :(得分:3)
夜间的完整错误消息非常清楚地说明了这里发生的情况。您将slice
移到函数from()
中,然后使用as_ref()
借用它,然后将其放在范围的末尾:
8 | impl<'a, T: Debug + Copy + 'a, R: AsRef<[T]> + 'a> From<R> for SliceWrapper<'a, T> {
| -- lifetime `'a` defined here
9 | fn from(slice: R) -> Self {
10 | Self{ slice: slice.as_ref(), pos: 0 }
| ^^^^^---------
| |
| borrowed value does not live long enough
| argument requires that `slice` is borrowed for `'a`
11 | }
| - `slice` dropped here while still borrowed
您正试图创建一个可以终身使用'a
的借项,但是您要借用的所有者slice
的寿命不足。
From
特性似乎不适用于此用例。该特征的想法是将某些数据的所有权移至新的类型,但是您的SliceWrapper
不具有所有权。我建议写一个自定义构造函数,而不是引用R
。
答案 1 :(得分:1)
您可以将转换限制为引用参数,然后有一种很好的方式来表达所需的借用-生存期取自输入引用:
impl<'a, T, R> From<&'a R> for SliceWrapper<'a, T>
where
T: Debug + Copy + 'a,
R: AsRef<[T]>
{
fn from(slice: &'a R) -> Self {
Self {
slice: slice.as_ref(),
pos: 0,
}
}
}
现在,您可以按照原来的推理了。
您有一个AsRef给您:&'x self -> &'x [T]
代表任何'x
,然后在其中输入&'a R
,这样您就得到了&'a [T]
。
参考引用From
有时存在,我认为这在类似引用到引用的转换中特别合适。 std中的一个示例是impl<'a> From<&'a str> for Cow<'a, str>