gpt4 book ai didi

rust - 在其函数中捕获变量的结构体

转载 作者:行者123 更新时间:2023-12-02 01:57:09 24 4
gpt4 key购买 nike

是否可以构建结构

struct MyFn<A, B> {
call: fn(A) -> B
}

这样它就能够捕获不可变的变量,如下面的代码片段所示?

let y: &f64 = &3.0
let my_fn: MyFn<f64, f64> {
call: |x| {
x + *y
}
}

我知道在这种情况下需要闭包,但是 call 的类型应该是什么,以便它可以捕获任何不可变的引用(例如函数引用)?

最佳答案

Is it possible to build the struct[...] such that it's able to capture...?

否 - 捕获涉及闭包,并且 MyFn::call 的类型是函数。 MyFn 可以通过将其类型设置为泛型类型或特征对象来将闭包存储在 call 中。

泛型非常高效,但使 MyFn 对于每个闭包具有不同的类型:

struct MyFn<A, B, F: Fn(A) -> B> {
call: F,
_data: PhantomData<(A, B)>,
}

let y: f64 = 3.0;
let my_fn: MyFn<f64, f64, _> = MyFn {
call: |x| x + y,
_data: PhantomData,
};

每个闭包具有单独的类型意味着您将无法轻松创建具有不同闭包的 MyFn 向量,或将其存储在需要拼写出类型的位置.

或者,您可以使call动态,即将其表达为特征对象。这将使 MyFn 仅在输入和输出类型上保持通用,并防止不同的闭包影响 MyFn 的类型。这种灵活性是以构造 MyFn 时的分配和调用 call 时的指针间接为代价的。 (提前的成本并不像有时想象的那么大,但了解这一点是件好事。)这样的 MyFn 看起来像这样:

struct MyFn<'a, A, B> {
call: Box<dyn Fn(A) -> B + 'a>,
}

let y: f64 = 3.0;
let my_fn: MyFn<f64, f64> = MyFn {
call: Box::new(|x| x + y),
};

与通用版本相比,动态版本似乎具有额外的生命周期,但这是因为生命周期是上一版本中闭包的未命名类型的一部分。

关于rust - 在其函数中捕获变量的结构体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69511080/

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