我想按照以下几点做点什么:
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..]
}
GetRef
特征中显式生命周期变量的要点是允许get_ref()
对象上的Foo
的返回值比Foo
本身更长,将将值的生命周期返回到Foo
缓冲区的生命周期。
但是,我还没有找到以编译器接受的方式为GetRef
实现Bar
的方法。我已尝试过上述几种变体,但似乎无法找到有效的变体。有没有任何理由从根本上无法做到这一点?如果没有,我该怎么做?
答案 0 :(得分:4)
将特质生命周期变量绑定到&amp; self lifetime
不可能。
有没有任何理由从根本上无法做到这一点?
是。拥有的向量与借用的切片不同。您的特征GetRef
仅对已经代表“贷款”并且不拥有切片的事物有意义。对于像Bar
这样的拥有类型,您无法安全地返回比Self
更长的借用切片。这就是借用检查器阻止避免悬挂指针的原因。
您尝试将life参数链接到Self
的生命周期。但Self
的生命周期不是其类型的属性。它只取决于定义此值的范围。这就是为什么您的方法无法工作的原因。
另一种看待它的方法是:在一个特征中,你必须明确Self
是否被方法借用及其结果。您定义了GetRef
特征,以返回不链接到Self
w.r.t的内容。寿命。所以,没有借款。因此,对于拥有数据的类型,它是不可实现的。如果不借用Vec
,则无法创建引用Vec
元素的借用切片。
如果没有,我该怎么做?
取决于“this”到底是什么意思。如果你想写一个可以为借用的和拥有的切片实现的“公分母”特征,你必须这样做:
trait GetRef {
fn get_ref(&self) -> &[u8];
}
这个特性的含义是get_ref
借用 Self
并返回一种“贷款”,因为当前的终身省略规则。它等同于更明确的形式
trait GetRef {
fn get_ref<'s>(&self) -> &'s [u8];
}
现在可以对两种类型实施:
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..] }
}
答案 1 :(得分:0)
你可以为自己创造不同的生命周期并导致你的特质:
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();
}
}