为什么我不能调用具有临时值的方法?

2023-12-01

我无法打电话Foo::new(words).split_first()在下面的代码中

fn main() {
    let words = "Sometimes think, the greatest sorrow than older";
/*
    let foo = Foo::new(words);
    let first = foo.split_first();
*/

    let first = Foo::new(words).split_first();

    println!("{}", first);
}

struct Foo<'a> {
    part: &'a str,
}

impl<'a> Foo<'a> {

    fn split_first(&'a self) -> &'a str {
        self.part.split(',').next().expect("Could not find a ','")
    }

    fn new(s: &'a str) -> Self {
        Foo { part: s }
    }
}

编译器会给我一条错误消息

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:8:17
   |
8  |     let first = Foo::new(words).split_first();
   |                 ^^^^^^^^^^^^^^^              - temporary value is freed at the end of this statement
   |                 |
   |                 creates a temporary which is freed while still in use
9  | 
10 |     println!("{}", first);
   |                    ----- borrow later used here
   |
   = note: consider using a `let` binding to create a longer lived value

如果我绑定的值Foo::new(words)首先,然后调用split_first方法没有问题。

这两种调用方法直观上应该是相同的,但又有些不同。


简短回答:去除'a的一生self的参数split_first: fn split_first(&self) -> &'a str (操场).

长答案:

当你编写这段代码时:

struct Foo<'a> {
    part: &'a str,
}

impl<'a> Foo<'a> {
    fn new(s: &'a str) -> Self {
        Foo { part: s }
    }
}

你告诉编译器所有Foo实例与某些生命周期相关'a必须等于或短于作为参数传递给的字符串的生命周期Foo::new。那一生'a may与每个人的一生不同Foo实例。当你写下:

let words = "Sometimes think, the greatest sorrow than older";
Foo::new(words)

编译器推断生命周期'a必须等于或短于words。除非有任何其他限制,编译器将使用words,即'static因此它在程序的整个生命周期内有效。

当您添加定义时split_first:

fn split_first(&'a self) -> &'a str

你正在添加一个额外的约束:你是说'a还必须等于或短于self。因此,编译器将采用生命周期中较短的一个words和临时的生命周期Foo实例,这是临时的生命周期。@AndersKaseorg 的回答解释了为什么这不起作用。

通过删除'a一生在self参数,我正在解相关'a从临时的生命周期中,所以编译器可以再次推断出'a是的生命周期words,这对于程序运行来说足够长了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我不能调用具有临时值的方法? 的相关文章

随机推荐