我发现生锈,生活困难。
例如,我正在尝试使用GUI:
#[macro_use]extern crate native_windows_gui as nwg;
use nwg::{Ui, Event, EventArgs};
nwg_template!(
head: setup_ui<&'static str>,
controls: [
("MainWindow", nwg_window!(title="Test1"; size=(180,50))),
("SetButton", nwg_button!(parent="MainWindow"; visible=false)),
("BackButton", nwg_button!(parent="MainWindow"; text="<"; position=(10,10); size=(30,30))),
("Text", nwg_textbox!(parent="MainWindow"; readonly=true; position=(40,10); size=(100,30))),
("NextButton", nwg_button!(parent="MainWindow"; text=">"; position=(140,10); size=(30,30)))
];
events: [
("SetButton", "Set", Event::Click, |app,_,_,_| {
let display = nwg_get_mut!(app; ("Text", nwg::TextBox));
let index = nwg_get!(app; ("Index", &str));
display.set_text(**index);
}),
("BackButton", "Back", Event::Click, |_,_,_,_| {}),
("NextButton", "Next", Event::Click, |_,_,_,_| {})
];
resources: [];
values: [
("Index", "Test")
]
);
fn create_ui(data: &'static str) -> Result<Ui<&'static str>, nwg::Error> {
let app: Ui<&'static str>;
match Ui::new() {
Ok(ui) => { app = ui; },
Err(e) => { return Err(e) }
}
if let Err(e) = setup_ui(&app) {
return Err(e);
}
app.pack_value(&"Data", &data);
app.trigger(&"SetButton", Event::Click, EventArgs::None);
if let Err(e) =app.commit() {
Err(e)
} else {
Ok(app)
}
}
fn main() {
let data = "Foo";
let _ui = create_ui(data).expect("Oups");
nwg::dispatch_events();
}
我不明白为什么在create_ui
函数中,data
的活动时间不够长,无法在app.pack_value()
中投放。
在我看来,'static
生命周期会让它存活足够长的时间。
但编译器确认它在create_ui
结束时死亡,因此不能用作app.pack_value("Data", &data);
我做错了什么?
答案 0 :(得分:2)
在不知道确切错误的情况下,很难确定,但我的猜测是:
fn create_ui(data: &'static str) -> Result<Ui<&'static str>, nwg::Error>
参数data
将借用一串静态生命周期。也就是说,它指向的东西(字符串数据)具有静态生命周期,但引用本身具有该函数的生命周期。现在让我们看一下native_windows_gui
包中的函数:
fn pack_value<T: Into<Box<T>> + 'static>(&self, id: &ID, value: T)
参数value
必须具有静态生命周期。还有一些其他要求,但它们并不相关。现在回到你的代码:
app.pack_value(&"Data", &data);
您正在传递pack_value
对 data
的引用,该引用已经是一个参考。也就是说,您传递的参数类型为&&'static str
。外部参考(你通过的那个)没有具有静态生命周期:它只与你的功能一样长。
C ++中的等价物就像
result_type create_ui(static char *str) {
Ui app = ...;
app.pack_value(&"Data", &str);
}
这可以在C ++中编译好,但是你没有传递字符串,你传递了参数的地址。这将编译正常,但行为将是未定义的,并且它将取决于该指针被取消引用时堆栈上的其他内容。在Rust中,编译器会告诉您错误的原因,而不是难以调试的问题。
解决方案与C ++相同:您需要删除额外的&
,并传递您收到的相同引用:
app.pack_value(&"Data", data);