Rust: заимствовать шашки в бесконечном цикле - PullRequest
0 голосов
/ 26 апреля 2019

В настоящее время я создаю приложение с основным циклом.Настройки добавляются в структуру в качестве ссылок, чтобы избежать упаковки.Проблема в том, что, несмотря на то, что программа проверки заимствований кажется совершенно корректной, она не проверяет бесконечные циклы.В качестве примера, это не компилируется:

struct Demo<'a> {
    data: Vec<&'a u8>,
}

impl<'a> Demo<'a> {
    fn new(data: Vec<&'a u8>) -> Self {
        Demo { data }
    }

    fn bug(mut self) -> ! {
        let a = 8;
        {
            self.data.push(&a);
            {
                self.forever();
            }
        }
    }

    fn forever(self) -> ! {
        loop {
            for dat in &self.data {
                println!("{}", dat);
            }
        }
    }
}

fn main() {
    let v = vec![&1, &1, &2, &3];
    Demo::new(v).bug();
}

Мой вопрос: как я могу реорганизовать приведенный выше код, чтобы избежать упаковки данных, но при этом иметь возможность использовать основной цикл.

Ответы [ 2 ]

2 голосов
/ 26 апреля 2019

В пределах impl<'a> Demo<'a> все self имеют одинаковый тип, для точно таких же 'a.Но в вашем случае вы пытаетесь сократить продолжительность жизни.Вы можете сделать это, повторно связав self:

let mut this = self;
// the compiler infers that `this` must have a shorter lifetime:
this.data.push(&a);
this.forever();

( ссылка на игровую площадку )

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

1 голос
/ 26 апреля 2019

Проблема здесь не столько в том, что средство проверки заимствований не может видеть бесконечный цикл, но в том, что вы активно лжете компилятору.При построении Demo<'a> в main() время жизни 'a является отдельным временем жизни (привязанным к области действия main()).В пределах bug() вы теперь выдвигаете новую ссылку, которая должна длиться до тех пор, пока время жизни 'a уже установлено как .Выхода из этого нет.

Однако вы можете создать ссылки, которые гарантированно будут жить как минимум до тех пор, пока любой срок действия:

fn bug(mut self) -> ! {
    let a: &'static u8 = &8;
    {
        self.data.push(a);
        {
            self.forever();
        }
    }
}

Этобудет работать, потому что независимо от того, что является 'a, 'static будет жить по крайней мере так же долго.

...