rust 如何推断方法(或函数)定义中的Lifetime注解的生存期?

g6ll5ycj  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(109)
struct V<'a> {
    s: &'a mut String,
    v: Vec<&'a String>
}

impl<'a, 'b> V<'a> {
    pub fn set(&mut self, s: &'b String){
        // self.s = s;
        self.s.push_str(s);
        self.v.push(s);
    }
}

个字符
但是self.s.push_str(s);是可以的。他们的函数签名是相同的(fn xxx(&mut self, &...))。这是什么原因?
这篇文章(2094-nll)我看了一遍又一遍,貌似懂了,其实并不懂,想通过学习NLL来提高自己的Rust编程习惯,然而还是很迷茫。

kx7yvsdv

kx7yvsdv1#

它们的函数签名是相同的(fn xxx(&mut self,&...))。
让我们来看看这个说法。

1. String::push_str

pub fn push_str(&mut self, string: &str)

字符串
它需要一个&str,也就是一片(utf-8编码的)字节,没有额外的生存期要求。
String具有Deref&str的隐式转换。
对于我们提供的参数(s: &'b String),这将导致&'b str。我们可以毫无问题地调用push_str,因为它对参数没有生存期要求。

2. Vec::push

pub fn push(&mut self, value: T)


T绑定到&'a StringVec的泛型参数)时,

pub fn push(&mut self, value: &'a String)


它需要一个&'a String,也就是对String对象的引用,该对象的生存期至少与'a一样长。
我们提供的参数再次是s: &'b String'b的生存期没有声明它与'a的关系,所以编译器不能假设它更长。因此编译器拒绝接受s: &'b String代替s: &'a String
对此的一个修正(编译器善意地建议)是要求对生命周期'b进行这样的限制:

impl<'a, 'b: 'a> V<'a> {
    pub fn set(&mut self, s: &'b String){
        self.s.push_str(s);
        self.v.push(s);
    }
}


或者,更常见的写法是(因为'b与我们的Vec无关):

impl<'a> V<'a> {
    pub fn set<'b: 'a>(&mut self, s: &'b String){
        self.s.push_str(s);
        self.v.push(s);
    }
}


最后,生命周期'b在这里实际上是完全不必要的。你可以在任何地方使用'a。(对于函数参数,生命周期总是最小边界)。

impl<'a> V<'a> {
    pub fn set(&mut self, s: &'a String){
        self.s.push_str(s);
        self.v.push(s);
    }
}


Demo

相关问题