我预计以下代码无法编译,但它确实编译了(playground):
fn main() {
(0..3)
.map(|i| {
struct S {
v: usize,
}
S { v: i }
})
.collect::<Vec<_>>();
}
我认为每个闭包调用都会定义一个新的结构类型(及其实例),因此结果不能作为某种单一类型的向量收集,但它似乎S
不是那么本地。
这在底层是如何工作的?我想要严格的解释,比如指向 Rust 参考页面的链接,所以添加了#language-lawyer
标签。
如果你在不了解 Rust 工作原理的情况下直接阅读上面的代码,我认为可以有两种解释,如下所示。我认为第二种解释是正确的,但代码编译的事实意味着第一种解释是正确的。但为什么呢?这就是我的问题。
解释1
//`S` is *global* in some sense.
struct S {
v: usize,
}
//Every invocation of the closure just creates a new instance of the type `S`.
for i in 0..3 {
vec.push(S { v: 0 });
}
解释2
{
//Every invocation of the closure declares a new struct type
// which is local to the invocation.
struct __S_anonymous_01 {
v: usize,
}
//And it then creates a new instance of that type.
vec.push(__S_anonymous_01 { v: 0 });
}
{
struct __S_anonymous_02 {
v: usize,
}
vec.push(__S_anonymous_02 { v: 1 });
}
{
struct __S_anonymous_03 {
v: usize,
}
vec.push(__S_anonymous_03 { v: 2 });
}
//And `__S_anonymous_{01|02|03}` are all different
// though they have the same structure
// because Rust doesn't support duck typing.
https://doc.rust-lang.org/stable/reference/items.html
(项目包括结构)。
通常,rust 不会定义依赖于值的类型。此外,在函数/闭包内定义的项(包括结构和函数等)不能使用来自其父级的值(例如变量)甚至通用参数,这进一步证实了项的嵌套除了可见性之外不会产生任何其他影响。