Почему заимствованное значение не живет достаточно долго, когда создается в конструкторе в аннотированном при жизни блоке impl? - PullRequest
0 голосов
/ 28 июня 2019

Я создаю небольшую программу для изучения ржавчины. Я пытаюсь сделать змею.

Змея состоит из частей змеи. Эти части змей работают как связанный список, каждая часть змей знает, какая часть змей является предыдущей. Сам Снейк знает, где его голова и хвост. Это выглядит так:

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>>,
}

Однако у меня проблемы с написанием конструктора Snake. Пока у меня есть это:

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 доживает только до конца конструктора, и он должен жить в течение времени жизни 'a, как определено в блоке impl.

Я знаю, что оно должно жить столько же, сколько вся змея, но почему это не работает? Я думаю, что часть змеи будет жить, пока жива сама змея - у змеи, которую я возвращаю, есть время жизни '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.,
        }
}

Почему это не работает? (У него точно такая же проблема, как и в предыдущем коде). Я беру часть змеи, помещаю ее в вектор, полный частей змеи, и сам вектор сохраняется в змею. Почему он не живет достаточно долго?

1 Ответ

2 голосов
/ 28 июня 2019

В итоге я использовал Vec в качестве связанного списка, поэтому мне не нужно реализовывать свой собственный.Если вы читаете это, я настоятельно рекомендую вам прочитать Learn Rust со слишком большим количеством связанных списков , как предложено @Jmb.

Это решение отчасти решает проблему, поэтому я выиграл 'Отметьте этот ответ как решение.Решение в путеводителе, указанном выше.Однако, если у вас есть похожая проблема, возможно, возможно решить вашу проблему с помощью аналогичного решения, как это - просто используйте Vec, не создавайте его самостоятельно.

Я только что сделал это и pop и push с snake_body при перемещении змеи.

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,
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...