通过Rust中的枚举类型实现惰性负载

问题描述 投票:0回答:1

在我的用例中,我有大量的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中的match语句存在所有权问题,因此无法使用。编译器建议我借用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。好的,没问题,让我们参考一下。唯一要注意的是,由于我正在对这些图像进行处理,因此它们必须是可变的:

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有点陌生,而且还有些不足。而且,我实际上不确定要实现我期望的目标该做什么。任何帮助,无论是告诉我如何使编译器满意,还是只是告诉我我要解决所有错误,都将不胜感激。

在我的用例中,我有大量的图层类型列表,其中包括图像数据和有关该图像的一些元数据:extern crate image;类型Img = image :: ImageBuffer

,Vec <:rgba>

rust lazy-loading borrowing
1个回答
0
投票
[我建议直接在get()类型上实现LazyImage方法,因为感觉加载图像是该类型的内部问题。
© www.soinside.com 2019 - 2024. All rights reserved.