为什么借用的值在生命周期注释的 impl 块的构造函数中创建时生存时间不够长?



我正在构建一个学习生锈的小程序。我正在尝试制作蛇。

蛇由蛇零件组成。这些蛇零件像链接列表一样工作,每个蛇零件都知道哪个蛇零件是前面的零件。蛇本身知道头和尾巴在哪里。看起来这样:

pub struct Snake<'a> {
    head: &'a SnakePart<'a>,
    tail: &'a SnakePart<'a>,
}
struct SnakePart<'a> {
    x: f32,
    y: f32,
    previous_part: Option<&'a SnakePart<'a>>,
}

但是,我编写蛇构造函数遇到问题。到目前为止,我都有:

impl<'a> Snake<'a> {
    pub fn new(x: f32, y: f32) -> Snake<'a> {
        let snake_part: SnakePart<'a> = SnakePart::new(x, y);
        Snake {
            head: &snake_part,
            tail: &snake_part,
            current_angle: 0.,
        }
    }
}

这创建了蛇,只有一个细分布(或蛇部分(,既是他的尾巴又是头。但是,这不会编译。编译器告诉我,snake_part仅活到构造函数的末端,它必须在impl块上定义的终生'a

我知道它必须只有整个蛇的生活,但是为什么这不起作用呢?我认为蛇部分将在蛇本身生活时生存 - 我返回的蛇有终生的'a。我如何说服生锈让蛇零件的寿命足够长?


我试图将所有蛇零件保存到蛇结构本身中。所以我以这种方式改变了:

pub struct Snake<'a> {
    ...
    snake_parts: Vec<SnakePart<'a>>,
}
impl<'a> Snake<'a> {
        let snake_part: SnakePart<'a> = SnakePart::new(x, y);
        let mut snake_parts: Vec<SnakePart<'a>> = Vec::with_capacity(1);
        snake_parts.push(snake_part);
        Snake {
            head: &snake_parts[0],
            tail: &snake_parts[0],
            snake_parts: snake_parts,
            current_angle: 0.,
        }
}

为什么这不起作用?(它与以前的代码完全相同(。我将蛇零件置于蛇的零件,将其推入蛇的零件,然后将矢量自身保存到蛇中。为什么它的寿命不够长?

我最终以vec为链接列表,因此我不必自己实现自己的。如果您正在阅读本文,我强烈建议您使用@JMB建议的完全链接的列表来学习Rust。

这种解决方案完全避免了问题,因此我不会将此答案标记为解决方案。解决方案在上面链接的指南中。但是,如果您有类似的问题,则可能可以通过类似的解决方案解决您的问题 - 只需使用Vec,不要自行构建它。

我刚刚从snake_body手中的 poppush做到了。

pub struct Snake {
    /// Snake body. The LAST item is head, the FIRST item is tail.
    snake_body: Vec<SnakePart>,
}
struct SnakePart {
    x: f32,
    y: f32,
}

最新更新