如何告诉编译器引用的struct变量的生命周期是什么?

时间:2018-05-23 21:02:15

标签: rust lifetime

请注意以下代码是一个简单的例子来说明我的问题,因此"test".to_string()否则我不会这样做。

struct Container<'a> {
    string: String,
    list: Vec<Item<'a>>,
}

impl<'a> Container<'a> {
    pub fn create() -> Container<'a> {
        let string = "test".to_string();

        Container {
            string,
            list: vec![],
        }
    }

    pub fn add(&mut self) {
        self.list.push(Item::create(&self.string));
    }
}

struct Item<'a> {
    string: &'a str,
}

impl<'a> Item<'a> {
    pub fn create(string: &'a str) -> Item<'a> {
        Item { string }
    }
}

fn main() {
    let container = Container::create();
    container.add();
    container.add();
}

当我尝试编译时,我收到以下错误:

error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> src/main.rs:17:37
   |
17 |         self.list.push(Item::create(&self.string));
   |                                     ^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
  --> src/main.rs:16:5
   |
16 | /     pub fn add(&mut self) {
17 | |         self.list.push(Item::create(&self.string));
18 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:17:37
   |
17 |         self.list.push(Item::create(&self.string));
   |                                     ^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 6:1...
  --> src/main.rs:6:1
   |
6  | impl<'a> Container<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^
   = note: ...so that the expression is assignable:
           expected Item<'a>
              found Item<'_>

我意识到这是因为编译器无法确定它应该用于self.string的生命周期。我已经查看了许多其他生命周期的例子,我知道需要做什么,但我不知道我应该使用什么语法来实现这一点。

我知道这可能是一件非常简单的事情,但我没有在Rust Book中找到任何内容,或者在这里解释了我所处的确切情况,并且我不太了解生命周期以至于应用其他解决方案我正在努力做什么。

这些是我尝试过的其他事情:

self.list.push(Item::create(&'a self.string));
error: expected `:`, found `self`
  --> lifeTest.rs:17:36
   |
17 |             self.list.push(Item::create(&'a self.string));
   |   
let reference: &'a str = &self.string;
self.list.push(Item::create(reference));
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> lifeTest.rs:17:29
   |
17 |             let reference: &'a str = &self.string;
   |                                      ^^^^^^^^^^^^
   |
pub fn add(&'a mut self) {
    self.list.push(Item::create(&self.string));
}
...
let mut container = Container::create();
error[E0499]: cannot borrow `container` as mutable more than once at a time
  --> lifeTest.rs:36:3
   |
35 |         container.add();
   |         --------- first mutable borrow occurs here
36 |         container.add();
   |         ^^^^^^^^^ second mutable borrow occurs here
37 |     }
   |     - first borrow ends here
struct Container<'a> {
    string: Option<&'a String>,
    list: Vec<Item<'a>>
}

....

let string = "test".to_string();

Container {
    string: Some(&string),
    list: vec![]
}
error[E0597]: `string` does not live long enough
  --> lifeTest.rs:11:19
   |
11 |                 string: Some(&string),
   |                               ^^^^^^ borrowed value does not live long enough
...

我觉得我已经接近最后一个,但我想尽可能避免使容器变得可变。

如何告诉编译器将生命周期'a用于它传递给Item的引用?

0 个答案:

没有答案