gpt4 book ai didi

callback - 如何将带有捕获的可变变量的回调像正常的可变借用一样对待?

转载 作者:行者123 更新时间:2023-11-29 07:54:34 26 4
gpt4 key购买 nike

Foo 可以使用方法 .modify() 修改:

struct Foo;
impl Foo {
fn modify(&mut self) {}
}

Bar 存储回调:

struct Bar<'a> {
callback: Box<FnMut() + 'a>,
}
impl<'a> Bar<'a> {
fn new<F: FnMut() + 'a>(f: F) -> Bar<'a> {
Bar {
callback: Box::new(f),
}
}
}

init() 获取一片 Bar 并执行它们的回调:

fn init(bars: &mut [Bar]) {
for b in bars {
(*b.callback)();
}
}

现在最有趣的是:

在循环中更改 Foo 效果很好;在循环的每次迭代中,可变地借用 foo 并调用 .modify():

fn main() {
let mut foo = Foo;

for _ in 0..10 {
foo.modify();
}
}

在回调中更改 Foo 不起作用:

fn main() {
let mut foo = Foo;

let mut bar1 = Bar::new(|| foo.modify());
let mut bar2 = Bar::new(|| foo.modify());

init(&mut [bar1, bar2]);
}

Try it on the playground ,它有一个错误:

error[E0499]: cannot borrow `foo` as mutable more than once at a time
--> src/main.rs:27:29
|
26 | let mut bar1 = Bar::new(|| foo.modify());
| -- --- previous borrow occurs due to use of `foo` in closure
| |
| first mutable borrow occurs here
27 | let mut bar2 = Bar::new(|| foo.modify());
| ^^ --- borrow occurs due to use of `foo` in closure
| |
| second mutable borrow occurs here
...
30 | }
| - first borrow ends here

如何对第2项进行类似的保证?

最佳答案

您可以使用 RefCell :

let foo = RefCell::new(Foo);

{
let bar1 = Bar::new(|| foo.borrow_mut().modify());
let bar2 = Bar::new(|| foo.borrow_mut().modify());
init(&mut [bar1, bar2]);
}

let mut foo = foo.into_inner(); // extract foo to use in external API

小心 borrow_mut(),如果值当前被借用,它会发生 panic 。


如果可以更改 Barinit(),则可以将值 foo 传递给 init() 与方法 modify() 分开:

struct Bar<'a> {
callback: Box<FnMut(&mut Foo) + 'a>,
}
impl<'a> Bar<'a> {
fn new<F: FnMut(&mut Foo) + 'a>(f: F) -> Bar<'a> {
Bar {
callback: Box::new(f),
}
}
}

fn init(bars: &mut [Bar], arg: &mut Foo) {
for b in bars {
(*b.callback)(arg);
}
}
let mut bar1 = Bar::new(|x| x.modify());
let mut bar2 = Bar::new(Foo::modify); // you can pass it without closure
init(&mut [bar1, bar2], &mut foo);

关于callback - 如何将带有捕获的可变变量的回调像正常的可变借用一样对待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38027461/

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