最近看了一下rust,发现安全性真的是很高,瞎写了一堆漏洞也编译不过,强行编译过了也利用不了,感觉快失业了(
所以在看rust的开发,有点想用rust开发一个linux下的调试器,毕竟有gui体验还是会好一点(
看了一圈rust的gui库,用的最多的似乎就是gtk-rs。
但是使用的过程确实有点蛋疼,自己写的项目包管理总是有问题,于是直接抄官方的样例:
[dependencies]
chrono = "0.4"
glib = "^0"
gio = "^0"
gdk = "^0"
gdk-pixbuf = "^0"
gtk = "^0"
pango = "^0"
cairo-rs = { version = "^0", features = ["png"] }
[features]
#default = ["gtk_3_22"]
gtk_3_10 = ["gtk/v3_10"]
gtk_3_16 = ["gtk_3_10", "gtk/v3_16"]
gtk_3_18 = ["gtk_3_16", "gtk/v3_18"] #for CI tools
gtk_3_20 = ["gtk_3_18", "gtk/v3_20"] #for CI tools
gtk_3_22 = ["gtk_3_20", "gtk/v3_22"] #for CI tools
但编译的时候整个项目就已经两个g了,感到非常难受。
本以为坑的事情已经过去了,最后在绑定按钮事件的时候也有一些问题。
以菜单选项的按钮监听为例,其函数原型是:
fn connect_activate<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
需要一个函数作为参数,但这里就有一个问题:函数必须是静态的。
初看似乎没有什么问题,但是我习惯的gui写法是将窗口封装成一个类,在类里面进行处理。所以下面的写法就会出错:
let about_submenu = MenuItem::new_with_label("about");
about_submenu.connect_activate(move |_|{
let messagebox = MessageDialog::new(Some(&self.mainWindow),DialogFlags::USE_HEADER_BAR,MessageType::Info,
ButtonsType::Ok,"test");
messagebox.run();
messagebox.destroy();
});
rust大概是认为这个函数的生命周期比self.mainWindow要长,所以这个地方报错了。
那么怎么解决这个问题呢(
翻了一下用这个库写的gui,发现大家定义了一个宏:
macro_rules! clone {
(@param _) => ( _ );
(@param x:ident) => (x );
((n:ident),+ => move || body:expr) => (
{( let n =n.clone(); )+
move || body
}
);
((n:ident),+ => move |(p:tt),+|body:expr) => (
{
( letn = n.clone(); )+
move |(clone!(@param p),)+|body
}
);
}
嗯,仔细看了一下就是一个clone,但是clone复制出来的这一份真的可以改变原来窗口里的东西吗(
当然可以了。
嗯,感觉连rust的门都没入进去,最近学习能力越来越菜了 orz。