Rust 防锈盖真的不需要类型注释吗?

Rust 防锈盖真的不需要类型注释吗?,rust,closures,Rust,Closures,我现在正在读《铁锈》这本书,我刚刚谈到了这个话题。 让我吃惊的一个细节是铁锈书上说 闭包不需要您注释参数的类型 我立即对此进行了测试,因为它看起来确实与生锈通常的工作原理背道而驰。因此,我复制,粘贴到我的代码,和。。。出现错误: fn一些_闭包(){ 让昂贵的|闭包=|num|{ println!(“计算缓慢…”); 线程::睡眠(持续时间::从秒(2)); 号码 }; } 我当然知道这个错误的含义,但我还是被它弄糊涂了,因为不仅是这本书,而且还说明了不需要注释,但我得到了这个错误 这只是一个

我现在正在读《铁锈》这本书,我刚刚谈到了这个话题。 让我吃惊的一个细节是铁锈书上说

闭包不需要您注释参数的类型

我立即对此进行了测试,因为它看起来确实与生锈通常的工作原理背道而驰。因此,我复制,粘贴到我的代码,和。。。出现错误:

fn一些_闭包(){
让昂贵的|闭包=|num|{
println!(“计算缓慢…”);
线程::睡眠(持续时间::从秒(2));
号码
};
}
我当然知道这个错误的含义,但我还是被它弄糊涂了,因为不仅是这本书,而且还说明了不需要注释,但我得到了这个错误


这只是一个尚未被记录的最新更改,还是我有什么误解?

编译器需要能够以某种方式推断参数的类型,这可以通过显式类型注释(如
num:i32
中的注释)或上下文信息(如

fn use_some_closure() {
    let expensive_closure = |num| {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
    };
    expensive_closure(42);
}
如果没有注释或用法,就无法确定
num
是什么


编译器需要能够以某种方式推断参数的类型,这可以通过显式类型注释(如
num:i32
中的注释)或上下文信息(如

fn use_some_closure() {
    let expensive_closure = |num| {
        println!("calculating slowly...");
        thread::sleep(Duration::from_secs(2));
        num
    };
    expensive_closure(42);
}
如果没有注释或用法,就无法确定
num
是什么

这本书和参考文献都明确指出不需要任何注释,但我得到了这个错误

不,这本书的关键词和参考是必需的,这与需要的不同。即使在通常不需要的情况下,某些东西也可能是上下文需要的

对于闭包,这种区别与“静态函数”(
fn
)相反,对于“静态函数”(
fn
),注释是一种语法要求:如果不提供类型注释,就不能编写有效的静态函数,而一般来说,可以编写没有类型注释的闭包

但是,编译器仍然需要知道闭包的具体类型,这需要能够推断参数和返回类型。如果因为没有足够的约束而不能,它将抱怨并需要显式指定的类型

在您的示例中,没有约束
num
的类型,因此rustc无法知道
num
的具体类型,因此无法推断闭包的具体类型

但在大多数情况下,例如

let it = repeat(5).map(|x| x+1);
编译器对此很满意,因为闭包的输入和输出类型必然是
map
提供的,即
Repeat::Item
,在本例中是
i32
(因为整数文本默认为禁止其他约束)

这本书和参考文献都明确指出不需要任何注释,但我得到了这个错误

不,这本书的关键词和参考是必需的,这与需要的不同。即使在通常不需要的情况下,某些东西也可能是上下文需要的

对于闭包,这种区别与“静态函数”(
fn
)相反,对于“静态函数”(
fn
),注释是一种语法要求:如果不提供类型注释,就不能编写有效的静态函数,而一般来说,可以编写没有类型注释的闭包

但是,编译器仍然需要知道闭包的具体类型,这需要能够推断参数和返回类型。如果因为没有足够的约束而不能,它将抱怨并需要显式指定的类型

在您的示例中,没有约束
num
的类型,因此rustc无法知道
num
的具体类型,因此无法推断闭包的具体类型

但在大多数情况下,例如

let it = repeat(5).map(|x| x+1);

编译器对此很满意,因为闭包的输入和输出类型必然是
map
提供的,即
Repeat::Item
,在本例中是
i32
(因为整数文本默认为禁止其他约束)。

num
绝对不能使用。所以绝对没有办法确定它的类型。是否要在闭包中使用
num
而不是
2
?这是一个打字错误吗?除了答案所说的以外,还有一些情况下,编译器可以找出类型,但还没有(现在)。您不应该将“不需要您注释”作为100%的保证,这更像是一种尽最大努力对类型进行直觉化的尝试。(但这与不存在此类尝试的函数有所不同。)此外,您可以指望编译器的未来版本在更少的情况下只需要注释,因为无法编译现有代码将是一个破坏性的更改。
num
绝对不会被使用。所以绝对没有办法确定它的类型。是否要在闭包中使用
num
而不是
2
?这是一个打字错误吗?除了答案所说的以外,还有一些情况下,编译器可以找出类型,但还没有(现在)。您不应该将“不需要您注释”作为100%的保证,这更像是一种尽最大努力对类型进行直觉化的尝试。(但这与不存在此类尝试的函数有所不同。)此外,您可以指望编译器的未来版本在更少的情况下只需要注释,因为无法编译现有代码将是一个破坏性的更改。