gpt4 book ai didi

multithreading - Rust 闭包如何工作以及它如何执行闭包?

转载 作者:行者123 更新时间:2023-11-29 07:52:06 24 4
gpt4 key购买 nike

它会创建一个新线程然后在新线程中执行那个匿名函数吗?

我在处理闭包时注意到许多所有权/借用限制。例如,如果我有 Fn()I cannot pass a mutable variable inside the closure or it needs to be wrapped with a Mutex :

fn helloworld(f: &Fn(f64)) {
f(42f64);
}

pub fn main() {
let mut killer = 2;
helloworld(&|n| {
println!("{}", n);
killer += 1;
});
}

如果闭包可能像那样不安全,那么幕后就会发生一些异步或并行的事情,这就是 Rust 编译器不允许我编译此类代码的原因。

我可能只是感到困惑,因为我来自 JavaScript/Python 世界,那里的情况完全不同。

最佳答案

这个问题有两个层次。

首先,Rust 中的闭包只是一种匿名定义的类型,它实现了一个或多个“可调用”特征。例如,这个:

fn main() {
let a = 6;
let closure = |b| {
println!("product is: {}", a * b);
};
closure(7);
}

被脱糖成类似的东西:

fn main() {
let a = 6;
let closure = {
struct Closure<'a> {
a: &'a i32,
}
impl<'a> Fn<(i32,)> for Closure<'a> {
extern "rust-call" fn call(&self, (b,): (i32,)) {
println!("product is: {}", (*self.a) * b);
}
}
impl<'a> FnMut<(i32,)> for Closure<'a> {
extern "rust-call" fn call_mut(&mut self, args: (i32,)) {
self.call(args)
}
}
impl<'a> FnOnce<(i32,)> for Closure<'a> {
type Output = ();
extern "rust-call" fn call_once(self, args: (i32,)) {
self.call(args)
}
}
Closure {
a: &a,
}
};
FnOnce::call_once(closure, (7,));
}

Note: the above code relies on unstable, internal details and will not work on a stable compiler. It is provided for explanation only; you should not use this pattern yourself.

不涉及线程,也没有发生任何神奇的事情。它们归结为带有额外初始“上下文”参数的常规函数​​调用。

这将我们带到第二层,这就是为什么您的特定代码不起作用:因为您告诉编译器禁止它。可调用对象的一个​​关键问题是如何将上下文传递给可调用对象的代码。这由 FnFnMutFnOnce 特征表示(在问题 When does a closure implement Fn, FnMut and FnOnce? 的答案中进行了解释)。通过采用 &Fn(f64),您已将自己限制为仅接受需要对其上下文进行不可变访问的闭包。

如果您希望闭包能够改变其上下文,则需要改用 FnMut。或者,如果您只需要调用一次闭包,则可以使用 FnOnce(尽管不像您在示例中那样作为特征对象)。

关于multithreading - Rust 闭包如何工作以及它如何执行闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45935100/

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