Rust 闭包真的不需要类型注解吗?
Do Rust closures really not need type annoations?
我目前正在阅读 Rust 这本书,我刚刚进入主题 closures
。
一个让我吃惊的细节是,Rust 书中说
Closures don’t require you to annotate the types of the parameters
我立即对此进行了测试,因为它看起来确实与 Rust 通常的工作方式有悖常理。因此,我复制了 exactly the closure they used,将其粘贴到我的代码中,然后...出现错误:
fn some_closure() {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
}
error[E0282]: type annotations needed
--> src/main.rs:14:30
|
14 | let expensive_closure = |num| {
| ^^^ consider giving this closure parameter a type
error: aborting due to previous error
我当然知道那个错误的意思,但我仍然对它感到困惑,因为不仅是书,而且 reference 都指定不需要注释,但我却收到这个错误。
这只是最近的更改,尚未记录在案,还是我误解了什么?
编译器需要能够以某种方式推断出参数的类型,这可以通过 num: i32
中的显式类型注释或
中的上下文信息来实现
fn use_some_closure() {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
expensive_closure(42);
}
如果没有注释或用法,就无法弄清楚 num
是什么。
the book, but also the reference specify that theres no annotations needed, yet I am getting this error.
不是,书和参考的关键词是required,和needed不同。即使通常不需要,也可以根据上下文需要某些内容。
对于闭包,区别在于“静态函数”(fn
),后者的注释是语法要求:如果没有注释,您将无法编写有效的静态函数提供类型注释,而一般来说您可以编写没有类型注释的闭包。
但是编译器仍然需要知道闭包的具体类型,这需要能够推断出参数 & return 类型。如果因为没有足够的约束而不能,它会抱怨并需要明确指定类型。
在你的例子中,num
的类型没有任何限制,所以 rustc 无法知道 num
的 concrete 类型是什么,因此无法推断闭包的具体类型。
但在大多数情况下,例如
let it = repeat(5).map(|x| x+1);
编译器对此很满意,因为闭包的输入和输出类型必然是 map
提供的,即 Repeat::Item
,在本例中是 i32
(因为这是整数文字默认禁止其他约束的内容。
我目前正在阅读 Rust 这本书,我刚刚进入主题 closures
。
一个让我吃惊的细节是,Rust 书中说
Closures don’t require you to annotate the types of the parameters
我立即对此进行了测试,因为它看起来确实与 Rust 通常的工作方式有悖常理。因此,我复制了 exactly the closure they used,将其粘贴到我的代码中,然后...出现错误:
fn some_closure() {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
}
error[E0282]: type annotations needed
--> src/main.rs:14:30
|
14 | let expensive_closure = |num| {
| ^^^ consider giving this closure parameter a type
error: aborting due to previous error
我当然知道那个错误的意思,但我仍然对它感到困惑,因为不仅是书,而且 reference 都指定不需要注释,但我却收到这个错误。
这只是最近的更改,尚未记录在案,还是我误解了什么?
编译器需要能够以某种方式推断出参数的类型,这可以通过 num: i32
中的显式类型注释或
fn use_some_closure() {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
expensive_closure(42);
}
如果没有注释或用法,就无法弄清楚 num
是什么。
the book, but also the reference specify that theres no annotations needed, yet I am getting this error.
不是,书和参考的关键词是required,和needed不同。即使通常不需要,也可以根据上下文需要某些内容。
对于闭包,区别在于“静态函数”(fn
),后者的注释是语法要求:如果没有注释,您将无法编写有效的静态函数提供类型注释,而一般来说您可以编写没有类型注释的闭包。
但是编译器仍然需要知道闭包的具体类型,这需要能够推断出参数 & return 类型。如果因为没有足够的约束而不能,它会抱怨并需要明确指定类型。
在你的例子中,num
的类型没有任何限制,所以 rustc 无法知道 num
的 concrete 类型是什么,因此无法推断闭包的具体类型。
但在大多数情况下,例如
let it = repeat(5).map(|x| x+1);
编译器对此很满意,因为闭包的输入和输出类型必然是 map
提供的,即 Repeat::Item
,在本例中是 i32
(因为这是整数文字默认禁止其他约束的内容。