LINUX.ORG.RU

Проблема с определением времени жизни/мутабельности

 


1

6

Есть программа

struct Page {
    content: i32,
}

struct Book<'a> {
    pages: Vec<Page>,
    bookmarks: Vec<&'a Page>,
}

fn main() {
    let mut book1 = Book {
        pages: Vec::new(),
        bookmarks: Vec::new(),
    };

    // добавление страниц
    book1.pages.push(Page { content: 42 });
    book1.pages.push(Page { content: 100500 });

    // добавление закладок
    book1.bookmarks.push(&book1.pages[0]);
    book1.bookmarks.push(&book1.pages[1]);

    println!("{}", book1.bookmarks[0].content);
}

которая запускается без ошибок, и печатает ожидаемый результат.

Каким образом можно определить такую функцию «add_bookmark», чтобы для добавления закладок, вместо операторов «book1.bookmarks.push(&book1.pages[0]);», можно было вызывать эту функцию «add_bookmark»?

В варианте

fn add_bookmark<'a>(book: &'a mut Book<'a>, page_no: usize) {
    book.bookmarks.push(&book.pages[page_no]);
}

возможен только один вызов

add_bookmark(&mut book1, 0);

Интересен вариант когда поле «bookmarks» хранит именно ссылки на страницы, а не номера страниц.


Наивные самоссылающиеся структуры в расте не поддерживаются из коробки.

Можно вставить костыль https://github.com/jpernst/rental (или еще выбрать из парочки аналогичных пакетов).

Можно перейти на Rc укзатели и что-то с ними замутить.

Можно дождаться https://github.com/rust-lang/rfcs/blob/master/text/2349-pin.md

Если в гугле вбить «rust self-referential structs» то можно найти много информации по вопросу, он часто возникает.

ozkriff ()