我正在学习Rust中的命名生命周期 ,我很难理解它们在实现一个特征时代表了什么.具体来说,我很难理解这段来自libserialize/hex.rs的代码.为了简洁起见,我删除了一些 comments .

pub trait ToHex {
    fn to_hex(&self) -> ~str;
}

static CHARS: &'static[u8] = bytes!("0123456789abcdef");

impl<'a> ToHex for &'a [u8] {
    fn to_hex(&self) -> ~str {
        let mut v = slice::with_capacity(self.len() * 2);
        for &byte in self.iter() {
            v.push(CHARS[(byte >> 4) as uint]);
            v.push(CHARS[(byte & 0xf) as uint]);
        }

        unsafe {
             str::raw::from_utf8_owned(v)
        }
    }
}

我理解CHARS定义中的'static生存期,但我对ToHex实现中定义的生存期感到困惑.What do named lifetimes represent in the implementation of a trait?

推荐答案

在那种特殊情况下,没有太多.&[u8]不是完全指定的类型,因为缺少生存期,并且实现必须针对完全指定的类型.因此,实现在任意(因为通用参数是无约束的)生存期'a上被参数化.

在这种情况下,你不会再使用它.但是,在某些情况下,当您希望将函数参数或返回值约束到同一生命周期时,您会这样做.

你可以这样写:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] {
    fn head(&self) -> Option<&'a T> {
        if self.len() == 0 { None } else { Some(&self[0]) }
    }
    …
}

这意味着返回值的生存期将与self'a相同.

顺便说一句,为了把事情搞砸,可以在每个函数上手动编写生命周期could:

impl<'a, T> ImmutableVector<'a, T> for &'a [T] {
    fn head<'a>(&'a self) -> Option<&'a T> {
        if self.len() == 0 { None } else { Some(&self[0]) }
    }
    …
}

…这表明,必须指定要为其实现的类型的生存期,这样才能真正指定fully个类型.它允许你为使用该生命周期的所有函数编写更少的代码.

Rust相关问答推荐

为什么父作用域中的变量超出了子作用域

如何在rust中有条件地分配变量?

在泛型 struct 的字段声明中访问关联的Conant

使用Clap时如何将String作为Into Str参数传递?

有没有办法在Rust中配置常量变量的值?

避免在Collect()上进行涡鱼类型的涂抹,以产生<;Vec<;_>;,_>;

为什么';t std::cell::ref使用引用而不是非空?

是否可以在不切换到下一个位置的情况下获得迭代器值:

如何迭代属性以判断相等性?

borrow 是由于对 `std::sync::Mutex>` 的解引用强制而发生的

为什么我可以使用 &mut (**ref) 创建两个实时 &mut 到同一个变量?

通过mem::transmute将数组展平安全吗?

Rust中是否可以在不复制的情况下从另一个不可变向量创建不可变向量?

从Rust 的临时文件中创建引用是什么意思?

如何获取函数中borrow 的切片的第一部分?

试图理解 Rust 中的可变闭包

是否有适当的方法在参考 1D 中转换 2D 数组

为什么可以从闭包中返回私有 struct

为什么这个闭包没有比 var 长寿?

在传输不可复制的值时实现就地枚举修改