我正在尝试使用Windows API编写Windows GUI程序,使用thread_local
保存所有创建的窗口或按钮。
use std::thread::Thread;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
// button window checkbox need impl this trait.
trait Wnd{
fn CreateWindow(&self)->int
{
// do some thing
0
}
}
pub struct Dust{
window_counter:int,
hInstance:int,
hookId: int,
widgets:HashMap<int, Rc<RefCell<Wnd>>>,
}
fn dust()->RefCell<Dust>{
unsafe{
let mut d = Dust{
window_counter:0,
hInstance:0,
hookId:0,
widgets: HashMap::new(),
};
return RefCell::new(d)
}
}
pub thread_local!(static TLS_DUST: RefCell<Dust> = dust());
fn main()
{
TLS_DUST.with( | d | {
let mut dust = d.borrow_mut();
dust.window_counter-=1;
});
}
当我构建时出现错误:
$ cargo build --verbose
Compiling dust v0.0.1 (file:///D:/msys64/home/BYWAYBOY/dust/examples)
Running `rustc D:\msys64\home\BYWAYBOY\dust\src\lib.rs --crate-name dust --crate-type lib -g -C metadata=3fbf7f518595f4d2 -C extra-filename=-3fbf7f518595f4d2 --out-dir D:\msys64\home\BYWAYBOY\dust\examples\target\deps --emit=dep-info,link -L D:\msys64\home\BYWAYBOY\dust\examples\target\deps -L D:\msys64\home\BYWAYBOY\dust\examples\target\deps`
D:\msys64\home\BYWAYBOY\dust\src\lib.rs:52:36: 52:39 error: explicit lifetime bound required
D:\msys64\home\BYWAYBOY\dust\src\lib.rs:52 widgets:HashMap<HWND, Rc<RefCell<Wnd>>>,
^~~
error: aborting due to previous error
Could not compile `dust`.
Caused by:
Process didn't exit successfully: `rustc D:\msys64\home\BYWAYBOY\dust\src\lib.rs --crate-name dust --crate-type lib -g -C metadata=3fbf7f518595f4d2 -C extra-filename=-3fbf7f518595f4d2 --out-dir D:\msys64\home\BYWAYBOY\dust\examples\target\deps --emit=dep-info,link -L D:\msys64\home\BYWAYBOY\dust\examples\target\deps -L D:\msys64\home\BYWAYBOY\dust\examples\target\deps` (status=101)
我只想使用HashMap将所有窗口和小部件存储在thread_local
中。
答案 0 :(得分:1)
这是一个带有您的代码版本的防火围栏:http://is.gd/1vAihA
以下是从围栏中复制的代码,让我解释一下我的更改。
您在上面提到的错误来自您的Dust结构声明,特别是widgets
字段。 Wnd
是一个特征,widget
字段的类型使用特征对象类型。特征对象类型允许在运行时进行动态分派,但是,正如编译器所说,您需要在特征对象上指定生命周期绑定。
我指定了特殊的生命周期限制static
,因为您将此与thread_local!
宏一起使用并将TLS_DUST
声明为静态。 'static
基本上表示此变量将在程序的整个生命周期中存在。
修正错误后,rustc
点击了另一个与Wnd
无关的错误Sized
。 Sized
是一种指定类型在编译时具有已知大小的类型。由于Wnd
是一个特征对象,因此可能是任意数量的不同大小,我们必须将其包装在Box<T>
中(将Box<T>
视为唯一的指针类型)。
我也借此机会为impl
写了Dust
。这是创建某种类型Dust::new()
的新变量的更惯用的方法。我保留了dust()
函数,将新的Dust
结构包装在RefCell
中。
最后,我修复了一些与驼峰案例代码相关的rustc
警告,生锈通常使用下划线来分隔单词。
代码:
use std::thread::Thread;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
// button window checkbox need impl this trait.
trait Wnd {
fn create_window(&self) -> int
{
// do some thing
0
}
}
struct Dust {
window_counter: int,
h_instance: int,
hook_id: int,
widgets: HashMap<int, Rc<RefCell<Box<Wnd + 'static>>>>, //'
}
impl Dust {
fn new() -> Dust {
Dust {
window_counter:0,
h_instance:0,
hook_id:0,
widgets: HashMap::new(),
}
}
fn dust() -> RefCell<Dust> {
RefCell::new(Dust::new())
}
}
pub thread_local!(static TLS_DUST: RefCell<Dust> = Dust::dust());
fn main()
{
TLS_DUST.with( | d | {
let mut dust = d.borrow_mut();
dust.window_counter-=1;
});
}