在我的用例中,我有大量的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>
get()
类型上实现LazyImage
方法,因为感觉加载图像是该类型的内部问题。