[英]Tying a trait lifetime variable to &self lifetime
I'd like to do something along the following lines: 我想按照以下方式做一些事情:
trait GetRef<'a> {
fn get_ref(&self) -> &'a [u8];
}
struct Foo<'a> {
buf: &'a [u8]
}
impl <'a> GetRef<'a> for Foo<'a> {
fn get_ref(&self) -> &'a [u8] {
&self.buf[1..]
}
}
struct Bar {
buf: Vec<u8>
}
// this is the part I'm struggling with:
impl <'a> GetRef<'a> for Bar {
fn get_ref(&'a self) -> &'a [u8] {
&self.buf[1..]
}
The point of the explicit lifetime variable in the GetRef
trait is to allow the return value of get_ref()
on a Foo
object to outlive the Foo
itself, tying the return value's lifetime to that of the lifetime of Foo
's buffer. GetRef
特性中显式生命周期变量的GetRef
是允许Foo
对象上的get_ref()
返回值超过Foo
本身,将返回值的生存期与Foo
缓冲区的生存期联系起来。
However, I haven't found a way to implement GetRef
for Bar
in a way that the compiler accepts. 但是,我还没有找到一种以编译器接受的方式实现
Bar
GetRef
的方法。 I've tried several variations of the above, but can't seem to find one that works. 我已经尝试了上述几种变体,但似乎找不到可行的变体。 Is there any there any reason that this fundamentally cannot be done?
是否有任何理由根本无法做到这一点? If not, how can I do this?
如果没有,我该怎么办?
Tying a trait lifetime variable to &self lifetime
将特质寿命变量与&self life绑定
Not possible. 不可能。
Is there any there any reason that this fundamentally cannot be done?
是否有任何理由根本无法做到这一点?
Yes. 是。 An owning vector is something different than a borrowed slice.
拥有向量与借来的切片有所不同。 Your trait
GetRef
only makes sense for things that already represent a “loan” and don't own the slice. 您的特征
GetRef
仅对已经表示“贷款”且不拥有切片的事物有意义。 For an owning type like Bar
you can't safely return a borrowed slice that outlives Self
. 对于
Bar
这样的拥有类型,您不能安全地返回借来的切片,而该切片的寿命超过Self
。 That's what the borrow checker prevents to avoid dangling pointers. 这就是借位检查器为避免指针悬而未决的原因。
What you tried to do is to link the lifetime parameter to the lifetime of Self
. 您尝试做的是将寿命参数链接到
Self
的寿命。 But the lifetime of Self
is not a property of its type . 但是,
Self
的寿命不是其类型的属性。 It just depends on the scope this value was defined in. And that's why your approach cannot work. 它仅取决于定义此值的范围。这就是您的方法无法起作用的原因。
Another way of looking at it is: In a trait you have to be explicit about whether Self
is borrowed by a method and its result or not. 看它的另一种方式是:在一个特质,你必须明确是否
Self
由的方法和它的结果还是不借来的。 You defined the GetRef
trait to return something that is not linked to Self
wrt lifetimes. 您定义了
GetRef
特征以返回未链接到Self
wrt生命周期的内容。 So, no borrowing. 因此,无需借款。 So, it's not implementable for types that own the data.
因此,它对于拥有数据的类型是不可行的。 You can't create a borrowed slice referring to a
Vec
's elements without borrowing the Vec
. 您不能创建一个借来片指的是
Vec
的元素,而无需借用Vec
。
If not, how can I do this?
如果没有,我该怎么办?
Depends on what exactly you mean by “this”. 取决于您“此”的确切含义。 If you want to write a “common denominator” trait that can be implemented for both borrowed and owning slices, you have to do it like this:
如果你要编写可以同时为借,拥有片实现的“共同点”特质,你必须做这样的:
trait GetRef {
fn get_ref(&self) -> &[u8];
}
The meaning of this trait is that get_ref
borrows Self
and returns a kind of “loan” because of the current lifetime elision rules. 此特征的含义是,由于当前的生命周期淘汰规则,
get_ref
借用了 Self
并返回一种“贷款”。 It's equivalent to the more explicit form 相当于更明确的形式
trait GetRef {
fn get_ref<'s>(&self) -> &'s [u8];
}
It can be implemented for both types now: 现在可以为两种类型实现它:
impl<'a> GetRef for Foo<'a> {
fn get_ref(&self) -> &[u8] { &self.buf[1..] }
}
impl GetRef for Bar {
fn get_ref(&self) -> &[u8] { &self.buf[1..] }
}
You could make different lifetimes for &self and result in your trait like that: 您可以为&self设置不同的生命,并导致如下特征:
trait GetRef<'a, 'b> {
fn get_ref(&'b self) -> &'a [u8];
}
struct Foo<'a> {
buf: &'a [u8]
}
impl <'a, 'b> GetRef<'a, 'b> for Foo<'a> {
fn get_ref(&'b self) -> &'a [u8] {
&self.buf[1..]
}
}
struct Bar {
buf: Vec<u8>
}
// Bar, however, cannot contain anything that outlives itself
impl<'a> GetRef<'a, 'a> for Bar {
fn get_ref(&'a self) -> &'a [u8] {
&self.buf[1..]
}
}
fn main() {
let a = vec!(1 as u8, 2, 3);
let b = a.clone();
let tmp;
{
let x = Foo{buf: &a};
tmp = x.get_ref();
}
{
let y = Bar{buf: b};
// Bar's buf cannot outlive Bar
// tmp = y.get_ref();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.