В моем случае использования у меня есть большой список Layer
типов, которые состоят из данных изображения и некоторых метаданных об изображении:
extern crate image;
type Img = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;
#[derive(Debug, Clone)]
struct Layer {
// some metadata fields
lazy_image: Img,
}
Пока все хорошо. Тем не менее, я выполняю некоторые отбраковки слоев перед фактической обработкой данных изображения, поэтому я хотел бы выполнить загрузку изображения ленивым образом, чтобы избежать необходимости загружать все изображения, которые мне на самом деле не нужны.
Это была моя первая попытка:
extern crate image;
type Img = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;
#[derive(Debug, Clone)]
enum LazyImage {
Path(String),
Image(Img)
}
#[derive(Debug, Clone)]
struct Layer {
// some metadata fields
lazy_image: LazyImage,
}
impl Layer {
fn get_image(&mut self) -> Img {
match self.lazy_image {
LazyImage::Image(img) => img,
LazyImage::Path(path) => {
let img = image::open(path).expect("Could not open image").to_rgba();
self.lazy_image = LazyImage::Image(img);
img
}
}
}
}
Как вы можете догадаться, это не сработало из-за проблем с владением моим заявлением о совпадении в get_image
. Компилятор предлагает заимствовать self.lazy_image
, по сути дела:
impl Layer {
fn get_image(&mut self) -> Img {
match &self.lazy_image {
LazyImage::Image(img) => img,
LazyImage::Path(path) => {
let img = image::open(path).expect("Could not open image").to_rgba();
self.lazy_image = LazyImage::Image(img);
img
}
}
}
}
Теперь, однако, у меня есть проблемы с типом: первая ветвь (если изображение уже загружено) возвращает ссылку &Img
вместо фактический Img
. Хорошо, нет проблем, давайте go полный справочник. Единственный улов в том, что, поскольку я выполняю обработку этих изображений, они должны быть изменяемыми:
impl Layer {
fn get_image(&mut self) -> &mut Img {
match &self.lazy_image {
LazyImage::Image(img) => img,
LazyImage::Path(path) => {
let img = image::open(path).expect("Could not open image").to_rgba();
self.lazy_image = LazyImage::Image(img);
&mut img
}
}
}
}
Теперь они одного типа, но различаются по изменчивости: в первой ветви (если изображения уже загружены) я получаю неизменную ссылку. Я пытался разворачиваться немного больше, но безуспешно, чтобы заставить это делать то, что я хочу.
Как вы можете сказать, я немного новичок в Rust и немного колеблюсь. Более того, я на самом деле не уверен, что я хочу, чтобы делал для достижения желаемой цели.
Любая помощь, рассказывает ли мне, как удовлетворить компилятор, или даже просто рассказывает мне, я все об этом ошибаюсь, буду очень признателен.