闭包不会捕获参数
Closure won't capture argument
我是 Rust 的初学者,我从教程中拿了一个例子并决定尝试一下。
Cacher 中的函数 fn new 没有看到第二个参数,这里是闭包,我试图传递 |num,num2|。我不知道我做错了什么。我们使用一个参数
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: Option<u32>,
multiplication : T,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T, multiplication : T) -> Cacher<T> {
Cacher {
calculation,
value: None,
multiplication,
}
}
fn generate_workout(intensity: u32, random_number: u32, test_test_multiplication: u32,) {
let mut expensive_result = Cacher::new( |num,num2| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num + num2
});
这里是错误
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> src/main.rs:43:32
|
43 | let mut expensive_result = Cacher::new( |num,num2| {
| ________________________________^^^^^^^^^^^__-
| | |
| | expected 2 arguments
44 | | println!("calculating slowly...");
45 | | thread::sleep(Duration::from_secs(2));
46 | | num + num2
47 | | });
| |_____- supplied 1 argument
|
note: associated function defined here
--> src/main.rs:21:8
|
21 | fn new(calculation: T, multiplication : T) -> Cacher<T> {
UPD
最后我找到了带括号的语法解释:
您的闭包类型被声明为采用一个 u32
参数和 return 一个 u32
值:
Fn(u32) -> u32
但是您提供的闭包接受两个 个参数。这表明应该更改闭包类型以指定闭包应该接受两个参数:
Fn(u32, u32) -> u32
此外,Cacher::new()
声明接受两个这样的闭包,但你只传递一个。
然而,当你解决这个问题时,你将 运行 陷入另一个问题:两个参数都被声明为相同的类型 (T
),但是每个闭包都有自己不同的类型,所以这个签名要求您两次传递完全相同的闭包类型,这可能不是您想要的。
您需要引入第二个泛型类型参数:
struct Cacher<T, U>
where
T: Fn(u32, u32) -> u32,
U: Fn(u32, u32) -> u32,
{
calculation: T,
value: Option<u32>,
multiplication : U,
}
impl<T, U> Cacher<T, U>
where
T: Fn(u32, u32) -> u32,
U: Fn(u32, u32) -> u32,
{
fn new(calculation: T, multiplication : U) -> Cacher<T, U> {
// ...
随着这变得越来越复杂,如果您使用盒装闭包,可能会更容易维护和推理您的代码,由于间接堆分配和动态调度,它有一个小的 运行时间性能损失,但可能值得不必为这么多类型而烦恼:
struct Cacher
{
calculation: Box<dyn Fn(u32, u32) -> u32>,
value: Option<u32>,
multiplication : Box<dyn Fn(u32, u32) -> u32>,
}
impl Cacher
{
fn new(
calculation: impl Fn(u32, u32) -> u32,
multiplication : impl Fn(u32, u32) -> u32
) -> Cacher {
Cacher {
calculation: Box::new(calculation),
value: None,
multiplication: Box::new(multiplication),
}
}
// ...
我是 Rust 的初学者,我从教程中拿了一个例子并决定尝试一下。 Cacher 中的函数 fn new 没有看到第二个参数,这里是闭包,我试图传递 |num,num2|。我不知道我做错了什么。我们使用一个参数
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: Option<u32>,
multiplication : T,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T, multiplication : T) -> Cacher<T> {
Cacher {
calculation,
value: None,
multiplication,
}
}
fn generate_workout(intensity: u32, random_number: u32, test_test_multiplication: u32,) {
let mut expensive_result = Cacher::new( |num,num2| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num + num2
});
这里是错误
error[E0061]: this function takes 2 arguments but 1 argument was supplied
--> src/main.rs:43:32
|
43 | let mut expensive_result = Cacher::new( |num,num2| {
| ________________________________^^^^^^^^^^^__-
| | |
| | expected 2 arguments
44 | | println!("calculating slowly...");
45 | | thread::sleep(Duration::from_secs(2));
46 | | num + num2
47 | | });
| |_____- supplied 1 argument
|
note: associated function defined here
--> src/main.rs:21:8
|
21 | fn new(calculation: T, multiplication : T) -> Cacher<T> {
UPD 最后我找到了带括号的语法解释:
您的闭包类型被声明为采用一个 u32
参数和 return 一个 u32
值:
Fn(u32) -> u32
但是您提供的闭包接受两个 个参数。这表明应该更改闭包类型以指定闭包应该接受两个参数:
Fn(u32, u32) -> u32
此外,Cacher::new()
声明接受两个这样的闭包,但你只传递一个。
然而,当你解决这个问题时,你将 运行 陷入另一个问题:两个参数都被声明为相同的类型 (T
),但是每个闭包都有自己不同的类型,所以这个签名要求您两次传递完全相同的闭包类型,这可能不是您想要的。
您需要引入第二个泛型类型参数:
struct Cacher<T, U>
where
T: Fn(u32, u32) -> u32,
U: Fn(u32, u32) -> u32,
{
calculation: T,
value: Option<u32>,
multiplication : U,
}
impl<T, U> Cacher<T, U>
where
T: Fn(u32, u32) -> u32,
U: Fn(u32, u32) -> u32,
{
fn new(calculation: T, multiplication : U) -> Cacher<T, U> {
// ...
随着这变得越来越复杂,如果您使用盒装闭包,可能会更容易维护和推理您的代码,由于间接堆分配和动态调度,它有一个小的 运行时间性能损失,但可能值得不必为这么多类型而烦恼:
struct Cacher
{
calculation: Box<dyn Fn(u32, u32) -> u32>,
value: Option<u32>,
multiplication : Box<dyn Fn(u32, u32) -> u32>,
}
impl Cacher
{
fn new(
calculation: impl Fn(u32, u32) -> u32,
multiplication : impl Fn(u32, u32) -> u32
) -> Cacher {
Cacher {
calculation: Box::new(calculation),
value: None,
multiplication: Box::new(multiplication),
}
}
// ...