在其函数中捕获变量的结构
A struct that captures variables in its function
是否可以构建结构
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),
};
与通用版本相比,动态版本似乎具有额外的生命周期,但那是因为生命周期是先前版本中未命名闭包类型的一部分。
是否可以构建结构
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),
};
与通用版本相比,动态版本似乎具有额外的生命周期,但那是因为生命周期是先前版本中未命名闭包类型的一部分。