tho*_*ice 2 ownership rust borrow-checker
是否可以构建结构
struct MyFn<A, B> {
call: fn(A) -> B
}
Run Code Online (Sandbox Code Playgroud)
这样它就能够捕获不可变的变量,如下面的代码片段所示?
let y: &f64 = &3.0
let my_fn: MyFn<f64, f64> {
call: |x| {
x + *y
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在这种情况下需要闭包,但是 的类型应该是什么,call以便它可以捕获任何不可变的引用(例如函数引用)?
是否可以构建 struct[...] 以便它能够捕获...?
否 - 捕获涉及闭包,并且类型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,
};
Run Code Online (Sandbox Code Playgroud)
每个闭包具有单独的类型意味着您将无法轻松创建MyFn具有不同闭包的 s 向量,或将其存储在需要拼写出类型的位置。
或者,您可以将其设为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),
};
Run Code Online (Sandbox Code Playgroud)
与通用版本相比,动态版本似乎具有额外的生命周期,但这是因为生命周期是前一版本中闭包的未命名类型的一部分。
| 归档时间: |
|
| 查看次数: |
355 次 |
| 最近记录: |