Rust 将特征寿命变量与&;自我寿命

Rust 将特征寿命变量与&;自我寿命,rust,lifetime,Rust,Lifetime,我想做以下几点: 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.b

我想做以下几点:

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..]
}
Foo GetRef和'a[u8]的特征GetRef{ &self.buf[1..] }
GetRef
特性中显式生命周期变量的要点是允许
Foo
对象上的
get_ref()
的返回值比
Foo
本身的生命周期长,将返回值的生命周期与
Foo
缓冲区的生命周期相关联

然而,我还没有找到一种方法来实现
GetRef
for
Bar
,以编译器可以接受的方式。我已经尝试了上述几种变体,但似乎找不到一种有效的。是否有任何理由根本无法做到这一点?如果没有,我怎么做

将特质生命周期变量与自我生命周期绑定(&S)

不可能

是否有任何理由根本无法做到这一点

对。拥有向量与借用的切片不同。您的trait
GetRef
仅对已经代表“贷款”且不拥有该片的事物有意义。对于拥有的类型,如
Bar
,您无法安全地返回比
Self
更有效的借用片段。这就是借阅检查器防止指针悬空的原因

您试图做的是将lifetime参数链接到
Self
的生存期。但是
Self
的生命周期不是它的类型属性。这取决于定义此值的范围。这就是为什么你的方法行不通

另一种看待它的方式是:在一种特质中,你必须明确说明
Self
是否被某个方法借用及其结果。您定义了
GetRef
trait以返回未链接到
Self
w.r.t.生命期的内容。所以,不要借钱。因此,对于拥有数据的类型,它是不可实现的。如果不借用
Vec
,则无法创建引用
Vec
元素的借用切片

如果没有,我怎么做

这取决于你所说的“这个”到底是什么意思。如果您想编写一个“公共分母”特性,该特性可用于借用和拥有切片,您必须这样做:

trait GetRef {
    fn get_ref(&self) -> &[u8];
}
此特征的含义是
get\u ref
借用
Self
,并返回一种“贷款”,因为当前的终身省略规则。它相当于更明确的形式

trait GetRef {
    fn get_ref<'s>(&self) -> &'s [u8];
}
trait GetRef{
fn获得参考{
fn get_ref(&self)->和[u8]{&self.buf[1..]}
}
条的impl GetRef{
fn get_ref(&self)->和[u8]{&self.buf[1..]}
}

您可以为&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();
    }
}
trait GetRef{
fn获取参考(&'b self)->&'a[u8];
}
结构Foo&'a[u8]{
&self.buf[1..]
}
}
结构条{
buf:Vec
}
//然而,条形图不能包含任何比它本身更长寿的东西
impl&'a[u8]{
&self.buf[1..]
}
}
fn main(){
设a=vec!(1为u8,2,3);
设b=a.clone();
让tmp;
{
设x=Foo{buf:&a};
tmp=x.get_ref();
}
{
设y=Bar{buf:b};
//酒吧的buf不能超过酒吧
//tmp=y.get_ref();
}
}

答案末尾的代码与我目前拥有的代码和我试图摆脱的代码非常接近。我想这样做的原因有点复杂,但归根结底,我需要能够得到比它们所来自的
Foo
更长的切片(但不是底层缓冲区)。@fjh我认为这里的关键点是,在特征中,生命周期必须始终具有相同的“形状”-它可以是实现者参数化的生存期,也可以是对象本身,但不能两者都是。在你的例子中,当
Bar
死亡时,缓冲区也会死亡-缓冲区不可能寿命更长。@Shepmaster是的,我意识到对
Bar
的引用不能超过
Bar
本身的寿命,但我希望有一种方法可以让它与
Foo
一起工作,而不使
Bar
不可能实现。我完全相信现在不能这样做。不过,很糟糕。
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();
    }
}