Как определить черту Index
для объекта, в котором данные хранятся в RefCell
в Rust? По сути, у меня есть объект, который я хотел бы проиндексировать, где иногда существуют данные, а иногда нет. Когда данных не существует, я хотел бы создать их, а затем вернуть соответствующую ссылку для операции индексации. В противном случае я бы хотел индексировать как обычно. В качестве упрощенного примера этого у нас есть код
// External libraries
use std::cell::{Ref, RefCell};
use std::ops::Index;
// Funny looking vector
struct MyVec<T> {
size: usize,
data: RefCell<Option<Vec<T>>>,
}
// Create a full vector
fn full<T>(size: usize, data: Vec<T>) -> MyVec<T> {
MyVec {
size,
data: RefCell::new(Some(data)),
}
}
// Creates an empty vector
fn empty<T>(size: usize) -> MyVec<T> {
MyVec {
size,
data: RefCell::new(None),
}
}
// Index from the vector
impl<T> Index<usize> for MyVec<T>
where
T: Clone + Default,
{
type Output = T;
fn index(&self, idx: usize) -> &Self::Output {
// Take out the data for processing
let data = self.data.replace(None);
// Make sure the data is full
let data = match data {
None => Some(vec![Default::default(); self.size]),
Some(_) => data,
};
// Put the data back inside the vector
let _ = self.data.replace(data);
// Return a reference to the element
Ref::map(self.data.borrow(), |data| match &data {
Some(data) => &data[idx],
None => unreachable!(),
})
}
}
// Test our functions
fn main() {
// Create an empty vector
let a = empty::<f32>(3);
// Print a value
println!("a(1): {}", a[1]);
}
. Он не компилируется и возвращает ошибку:
error[E0308]: mismatched types
--> src/test02.rs:48:9
|
48 | / Ref::map(self.data.borrow(), |data| match &data {
49 | | Some(data) => &data[idx],
50 | | None => unreachable!(),
51 | | })
| |__________^ expected &T, found struct `std::cell::Ref`
|
= note: expected type `&T`
found type `std::cell::Ref<'_, T>`
help: consider borrowing here
|
48 | &Ref::map(self.data.borrow(), |data| match &data {
49 | Some(data) => &data[idx],
50 | None => unreachable!(),
51 | })
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
Конечно, Ref
не совпадает с &
. Тем не менее, как это можно исправить?
В случае, если это имеет значение, мне не обязательно нужно a RefCell
. На самом деле, у меня есть тип перечисления с различными параметрами. Тем не менее, дело остается тем же. Иногда данные существуют. Иногда данные не. Когда данных не существует, я хотел бы создать их до того, как мы их проиндексируем.