mrjbom
@mrjbom

Возврат структуры со ссылкой на значение и значением?

Пытаюсь вернуть из функции структуру которая содержит вектор и ссылку на значение из вектора:
pub struct Graphics<'a> {
    adapters: Vec<Adapter>,
    adapter: &'a Adapter,
}


impl Graphics<'_> {
    pub fn new(args: &Args) -> Result<Self, anyhow::Error> {
        let adapters: Vec<Adapter> = instance.enumerate_adapters();
        let adapter: &Adapter = select_adapter(&adapters)?;

        Self {
            adapters,
            adapter,
        }
    }
}

// Возвращает ссылку на элемент вектора
fn select_adapter<'a>(adapters: &'a Vec<Adapter>) -> Result<&'a Adapter, anyhow::Error>;


Сталкиваюсь с такой ошибкой: `adapters` does not live long enough
Полный текст

pub fn new(args: &Args) -> Result<Self, anyhow::Error> {
   |                                --------------------------- return type is std::result::Result<Graphics<'1>, anyhow::Error>
...
32 |         let adapters = instance.enumerate_adapters(get_wgpu_backend());
   |             -------- binding `adapters` declared here
33 |         // Select adapter
34 |         let adapter = select_adapter(&instance, &adapters, args.adapter_index, &surface)?;
   |                                                 ^^^^^^^^^ borrowed value does not live long enough
...
                 // Тут возврат Self из функции
74 |             adapter,
   |             ------- this usage requires that `adapters` is borrowed for `'1`
...
78 |     }
   |     - `adapters` dropped here while still borrowed


Что за this usage requires that `adapters` is borrowed for `'1` и особенно что за `adapters` dropped here while still borrowed? Ведь adapters ни не дропается, а в Self перемещается, очевидный же бред в ошибке.
Как это исправлять?

Решил для упрощения кода повторить его на Rust Playground
struct A;

struct S<'a> {
    a_vec: Vec<A>,
    a_ref: &'a A
}

impl S<'_> {
    fn new() -> Self {
        let a_vec = vec![A, A, A];
        let a_ref = get_ref(&a_vec);

        Self {
            a_vec,
            a_ref,
        }
    }
}

fn get_ref<'a>(a_vec: &'a Vec<A>) -> &'a A {
    &a_vec[0]
}

Но тут к моему удивлению совершенно другие ошибки:
spoiler

error[E0515]: cannot return value referencing local variable `a_vec`
  --> src/main.rs:13:9
   |
11 |           let a_ref = get_ref(&a_vec).unwrap();
   |                               ------ `a_vec` is borrowed here
12 |
13 | /         Self {
14 | |             a_vec,
15 | |             a_ref
16 | |         }
   | |_________^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `a_vec` because it is borrowed
  --> src/main.rs:14:13
   |
9  |       fn new() -> Self {
   |                   ---- return type is S<'1>
10 |           let a_vec = vec![A, A, A];
   |               ----- binding `a_vec` declared here
11 |           let a_ref = get_ref(&a_vec).unwrap();
   |                               ------ borrow of `a_vec` occurs here
12 |
13 | /         Self {
14 | |             a_vec,
   | |             ^^^^^ move out of `a_vec` occurs here
15 | |             a_ref
16 | |         }
   | |_________- returning this value requires that `a_vec` is borrowed for `'1`


И почему тут ошибки другие, если код в целом тот-же?
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
vabka
@vabka Куратор тега Rust
У тебя там self referential struct, так что придётся при помощи NonNull указателей сделать и запретить перемещение структуры при помощи PhantomPin.
Лайфтайма наподобие 'self нету
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы