Насколько безопасно это поведение GTK-rs Builder::get_object?
На языке программирования Rust он говорит что-то вроде:
Переместить семантику
Однако здесь есть еще несколько тонкостей: Rust гарантирует, что существует ровно одна привязка к любому данному ресурсу. Например, если у нас есть вектор, мы можем присвоить его другой привязке:
Но я обнаружил, что могу сделать это с помощью gtk-rs:
let label1: gtk::Label = builder.get_object("label1").unwrap();
let label1_test: gtk::Label = builder.get_object("label1").unwrap();
Оба сейчас указывают на один и тот же ресурс "или что-то случится со мной".
Builder::get_object
определяется как:
pub fn get_object<T: IsA<Object>>(&self, name: &str) -> Option<T> {
unsafe {
Option::<Object>::from_glib_none(
ffi::gtk_builder_get_object(self.to_glib_none().0, name.to_glib_none().0))
.and_then(|obj| obj.downcast().ok())
}
}
Хотя на самом деле это не что-то напрямую от Rust, просто от gtk-rs, мне было интересно, прав ли я и насколько это точно.
Может быть, это можно использовать Rc
?
1 ответ
Объекты GTK/GLib (GObject) напрямую осуществляют подсчет ссылок, аналогично типу Arc в Rust. Вы можете безопасно иметь несколько ссылок на один и тот же объект, и как только последний выйдет из области видимости, объект будет уничтожен.
Для изменчивости, в Rust, gtk-rs использует внутреннюю изменчивость (концептуально). Таким образом, вы можете изменить каждую ссылку на один и тот же объект, даже если их несколько. Реализация объектов должна справиться с этим (и должна в любом случае, потому что именно так все работает в GTK/GLib в C).