Как я могу вернуть ссылку на вложенный элемент вложенной записи в структуре? - PullRequest
0 голосов
/ 28 мая 2019

У меня есть структура с вектором других структур:

pub struct StructB {
    value1: u64,
    value2: String,
}

pub struct StructA {
    array: Vec<StructB>,
}

StructB постоянно; во время создания StructA array заполняется объектами, которые считываются из файла, и вряд ли будет изменен.

Я хотел бы иметь функцию для получения элемента StructB, соответствующего входному параметру: get_structB(input: u64) -> &StructB. Для простоты предположим, что мы просто вернем элемент с заданным индексом, предполагая, что кто-то еще проверяет границы.

Я борюсь с тем, как реализовать это в Rust. Я хотел бы вернуть своего рода ссылку «только для чтения» или ссылку на объект, который является неизменным, но не делает копию. Я не могу найти правильный способ сделать это.

impl StructA {
    fn get_structB(&self, idx: u64) -> Box<StructB> {   // Or should I use here Rc?
        // Here I don't want to consume self just return reference wrapped to the idx element
        // Should I implement something like as_ref() for the StructA?
        self.array[idx]     // That of course won't compile
    }
}

1 Ответ

0 голосов
/ 28 мая 2019
impl StructA {
    fn get_structB(&self, i: usize) -> &StructB {
        return &self.array[i];
    }
}

Это делает трюк.Однако вы можете столкнуться с некоторой проблемой, если напишите следующее:

// `a` is a StructA instance
let bb = a.get_struct_b(0);
println!("{:?}", bb);
drop(a);              // move out of `a` occurs here
println!("{:?}", bb); // borrow of `a` is used here

Вам придется изменить определение структуры и использовать Rc для написания функции.Rc оказывает небольшое влияние на производительность и делает код более сложным, поэтому вы можете использовать его только тогда, когда знаете, что данные будут использоваться после перемещения StructA.

pub struct StructA {
    array: Vec<Rc<StructB>>,
}

impl StructA {
    fn get_structB(&self, i: usize) -> Rc<StructB> {
        return Rc::clone(self.array[i]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...