gpt4 book ai didi

rust - 我不安全的唯一选择是传递对此方法的引用以期望关闭吗?

转载 作者:行者123 更新时间:2023-12-03 11:33:37 24 4
gpt4 key购买 nike

我使用的是cursive_table_view crate ,并且该表具有set_on_submit方法,当用户在表中选定的行上按鼠标键时,您将向该方法传递闭包。所述方法的签名为:

 pub fn set_on_submit<F>(&mut self, cb: F)
where
F: Fn(&mut Cursive, usize, usize) + 'static,
在闭包内部,我试图使用包含此代码的函数中实际作为参数的东西。我只是将该参数声明为&'static,这一切都很好,而且是预期的。当然,现在,我已经将问题移到了函数的调用者那里。
fn my_function(param: &'static MyType) {
let table = TableView::new();
table.set_on_sumbit(|cur, row, index| {
do_something_with(param);
}
}
最终,我不得不将变量声明为静态变量以将其作为参数传递给该函数,但是由于我需要在调用之前(以及声明之后)修改此变量,因此它必须是静态可变的。现在的问题是,当我尝试修改变量时,编译器说我只能在不安全的情况下这样做。
我相信我了解以上所有原因。闭包将在UI中的某个事件上被调用,因此有意义的是它可以存在于整个程序中。
我已经在Rc上尝试了几种选择,并阅读了大量有关生存期,甚至线程和消息的信息,但是我觉得我在盲目的尝试某些事情时并没有真正的理解。我现在所处的位置是我相信自己能够理解,但是对于必须遵循不安全的路线建议我感到不舒服。
可以避免吗?我的模式一开始是错误的吗?
我不想添加更多代码以使解释与其他所有内容无关,但是如果有更多代码有助于理解该问题,我当然很乐意进行编辑。另外,在将引用传递给闭包时,我真的不需要再修改结构了,以防有助于找到一条可行的解决方案。

最佳答案

可以将引用视为主要(不包括&'static和其他一些情况)用于临时对象,尤其是仅存在于堆栈框架中的临时对象。因此,请勿尝试将引用用于用户界面回调之类的事情。
以下是改用std::rc::Rc的方法,该方法可确保数据的生存时间与所需时间一样长。

use std::rc::Rc;

fn my_function(param: Rc<MyType>) { // changed parameter type
let table = TableView::new();
table.set_on_submit(|cur, row, index| {
do_something_with(&param); // & enables conversion to &MyType
}
}
现在,为了使用此功能,您需要进行安排,以便数据由 Rc拥有。无法进行上述类型的回调,也不能直接拥有 let data = MyType {...},因为 数据必须由Rc 拥有。 (但是,如果有用,您可以对其进行初始化,然后将其放入 Rc中。)
fn main() {
// Wrap it as soon as you construct it.
// (Or at least before you start using callbacks.)
let my_app_data = Rc::new(MyType {
// whatever fields or constructor...
});

// Call the function. `.clone()` here makes a copy of the `Rc` refcounted pointer,
// not the underlying data.
my_function(my_app_data.clone());
}
如果您的程序使用线程,则必须使用线程安全引用计数器 std::sync::Arc而不是 Rc
如果要在存在回调的情况下修改数据(无论是在回调中还是在其他位置),则还需要在 RefCell内使用 std::sync::Mutex(或线程安全的 RwLock/ Rc),这会带来一些麻烦。

关于rust - 我不安全的唯一选择是传递对此方法的引用以期望关闭吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66056879/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com