如何修改 Rust 闭包捕获的变量?
How can I modify a variable captured by a Rust closure?
我正在尝试为 Rust 应用程序制作一个 GUI,看起来它对我来说效果很好 imgui-rs. All I want to be able to do is get some input values from the user, and output a changing png. I had some trouble getting the boilerplate started, but the provided repository has support code 它对我来说效果很好,足以让 hello world 演示正常工作,但是当我尝试修改它以获取输入并更改显示,我 运行 陷入所有权问题。我现在要做的是让用户输入图像名称,然后打开该文件并在 GUI 中显示它。
这是我现在拥有的(不包括上面链接的支持代码):
struct State {
path: ImString,
has_image: bool,
}
impl Default for State {
fn default() -> Self {
Self {
path: ImString::with_capacity(128),
has_image: false,
}
}
}
fn main() {
let mut system = imgui_support::init(file!()); // this is from support code
let mut state = State::default();
system.main_loop(move |_, ui| {
Window::new(im_str!("hello world"))
.size([330.0, 110.0], imgui::Condition::FirstUseEver)
.position([0f32, 0f32], imgui::Condition::FirstUseEver)
.build(ui, || {
ui.input_text(im_str!("File path"), &mut state.path).build();
if ui.small_button(im_str!("Submit file")) {
system.add_img(state.path.to_str()); // try to open file and parse as texture
}
ui.separator();
});
if state.has_image {
Window::new(im_str!("Render:"))
.size([720f32, 720f32], imgui::Condition::FirstUseEver)
.build(ui, || {
imgui::Image::new(TextureId::new(0), [720f32, 720f32]).build(ui);
});
}
});
}
我作为方法添加到 System
结构上的 add_img
函数定义为:
pub fn add_img(&mut self, path: &str) -> TextureId {
let textures: &mut Textures<Texture> = &mut self.renderer.textures();
let res_img = image::open(path);
match res_img {
Ok(image) => {
let image = image.to_rgba8();
let dimensions = image.dimensions();
let texture = RawImage2d::from_raw_rgba(image.into_raw(), dimensions);
let gl_texture = Texture2d::new(self.display.get_context(), texture).unwrap();
let texture = imgui_glium_renderer::Texture {
texture: Rc::new(gl_texture),
sampler: SamplerBehavior {
magnify_filter: MagnifySamplerFilter::Linear,
minify_filter: MinifySamplerFilter::Linear,
..Default::default()
},
};
textures.insert(texture)
}
Err(_) => TextureId::new(usize::MAX),
}
}
现在,我收到错误 use of moved value system
,无论我如何尝试 ar运行ge 数据,我似乎都无法避免移动后使用错误。
是否有更好的方法来组织我的代码,或者可能是不那么健壮的 Rust GUI 库,因为我不需要 99% 的 imgui 功能?
问题是,方法 main_loop
取得了 system
的所有权。之后系统将永远无法供您使用。
一个快速修复方法是更新方法 main_loop
以将 renderer
和 display
传递给闭包。
像这样:
pub fn main_loop<F>(self, mut run_ui: F)
where F: FnMut(&mut bool, &mut Ui, &mut Renderer, &mut glium::Display) + 'static {}
然后在调用 run_ui
时只需添加渲染器和显示。
run_ui(&mut run, &mut ui, &mut renderer, &mut display);
方法add_img
应该做成一个独立的函数,将渲染器和显示分开,不依赖于系统。
pub fn add_img(path: &str, renderer: &mut Renderer, display: &mut glium::Display) -> TextureId {}
我正在尝试为 Rust 应用程序制作一个 GUI,看起来它对我来说效果很好 imgui-rs. All I want to be able to do is get some input values from the user, and output a changing png. I had some trouble getting the boilerplate started, but the provided repository has support code 它对我来说效果很好,足以让 hello world 演示正常工作,但是当我尝试修改它以获取输入并更改显示,我 运行 陷入所有权问题。我现在要做的是让用户输入图像名称,然后打开该文件并在 GUI 中显示它。
这是我现在拥有的(不包括上面链接的支持代码):
struct State {
path: ImString,
has_image: bool,
}
impl Default for State {
fn default() -> Self {
Self {
path: ImString::with_capacity(128),
has_image: false,
}
}
}
fn main() {
let mut system = imgui_support::init(file!()); // this is from support code
let mut state = State::default();
system.main_loop(move |_, ui| {
Window::new(im_str!("hello world"))
.size([330.0, 110.0], imgui::Condition::FirstUseEver)
.position([0f32, 0f32], imgui::Condition::FirstUseEver)
.build(ui, || {
ui.input_text(im_str!("File path"), &mut state.path).build();
if ui.small_button(im_str!("Submit file")) {
system.add_img(state.path.to_str()); // try to open file and parse as texture
}
ui.separator();
});
if state.has_image {
Window::new(im_str!("Render:"))
.size([720f32, 720f32], imgui::Condition::FirstUseEver)
.build(ui, || {
imgui::Image::new(TextureId::new(0), [720f32, 720f32]).build(ui);
});
}
});
}
我作为方法添加到 System
结构上的 add_img
函数定义为:
pub fn add_img(&mut self, path: &str) -> TextureId {
let textures: &mut Textures<Texture> = &mut self.renderer.textures();
let res_img = image::open(path);
match res_img {
Ok(image) => {
let image = image.to_rgba8();
let dimensions = image.dimensions();
let texture = RawImage2d::from_raw_rgba(image.into_raw(), dimensions);
let gl_texture = Texture2d::new(self.display.get_context(), texture).unwrap();
let texture = imgui_glium_renderer::Texture {
texture: Rc::new(gl_texture),
sampler: SamplerBehavior {
magnify_filter: MagnifySamplerFilter::Linear,
minify_filter: MinifySamplerFilter::Linear,
..Default::default()
},
};
textures.insert(texture)
}
Err(_) => TextureId::new(usize::MAX),
}
}
现在,我收到错误 use of moved value system
,无论我如何尝试 ar运行ge 数据,我似乎都无法避免移动后使用错误。
是否有更好的方法来组织我的代码,或者可能是不那么健壮的 Rust GUI 库,因为我不需要 99% 的 imgui 功能?
问题是,方法 main_loop
取得了 system
的所有权。之后系统将永远无法供您使用。
一个快速修复方法是更新方法 main_loop
以将 renderer
和 display
传递给闭包。
像这样:
pub fn main_loop<F>(self, mut run_ui: F)
where F: FnMut(&mut bool, &mut Ui, &mut Renderer, &mut glium::Display) + 'static {}
然后在调用 run_ui
时只需添加渲染器和显示。
run_ui(&mut run, &mut ui, &mut renderer, &mut display);
方法add_img
应该做成一个独立的函数,将渲染器和显示分开,不依赖于系统。
pub fn add_img(path: &str, renderer: &mut Renderer, display: &mut glium::Display) -> TextureId {}