【发布时间】:2020-12-01 08:39:51
【问题描述】:
费里斯船长有一张地图 (seven_seas.png),他在该区域隐藏了多个宝藏(坐标为 (5,7) 和 (7,9))。他想为每个宝藏创建一个单独的藏宝图。原图不得改动。
他决定为此使用 rust 和 image crate。
extern crate image;
use crate::image::GenericImage;
struct Desk {
map_of_seven_seas: image::DynamicImage,
colored_ink: image::Rgba<u8>,
}
impl Desk {
fn create_treasure_map(mut self, x: u32, y:u32) -> image::DynamicImage {
self.map_of_seven_seas.put_pixel(x, y, self.colored_ink);
self.map_of_seven_seas
}
}
fn main() {
let desk = Desk {
map_of_seven_seas: image::open("seven_seas.png").unwrap(),
colored_ink: image::Rgba([255, 0, 0, 255]), // red
};
println!("Marking my treasures!");
// works fine
let treasure_map_0 = desk.create_treasure_map(5, 7);
treasure_map_0.save("treasure_map_0.png").unwrap();
// breaks
let treasure_map_1 = desk.create_treasure_map(7, 9);
treasure_map_1.save("treasure_map_1.png").unwrap();
}
当费里斯船长意识到他的计划存在缺陷时,乌云遮住了天空:
error[E0382]: use of moved value: `desk`
--> src/main.rs:30:26
|
19 | let desk = Desk {
| ---- move occurs because `desk` has type `Desk`, which does not implement the `Copy` trait
...
26 | let treasure_map_0 = desk.create_treasure_map(5, 7);
| ---- value moved here
...
30 | let treasure_map_1 = desk.create_treasure_map(7, 9);
| ^^^^ value used here after move
error: aborting due to previous error
摩天船长现在有麻烦了。看来他的办公桌只能使用一次。他评估了 Mate Cargo 所暗示的内容,并尝试推导出 Desk 的 Copy 特征(将 #[derive(Clone, Copy)] 添加到结构中)。但他又一次失败了:
error[E0204]: the trait `Copy` may not be implemented for this type
--> src/main.rs:4:17
|
4 | #[derive(Clone, Copy)]
| ^^^^
5 | struct Desk {
6 | map_of_seven_seas: image::DynamicImage,
| -------------------------------------- this field does not implement `Copy`
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
image::DynamicImage 不能被复制,他也不能为它派生Copy,因为它是 crate 的一部分。
费里斯船长每次想要创建藏宝图(包括从文件系统加载map_of_the_seven_seas)时都必须创建一个新的Desk吗?或者有没有更好的方法来重复使用 Desk?
这对我来说是一个学习练习,所以一个带有解释的好解决方案会比一个聪明的 hack 更好。
【问题讨论】:
标签: image rust move-semantics deep-copy