为什么局部变量的寿命不够 thread::scoped?

Why doesn't a local variable live long enough for thread::scoped?

既然示例 2 可以正常编译,为什么示例 1 不能编译?示例之间的唯一区别是示例 1 中 value 是函数局部变量,而示例 2 中 value 是函数的参数。

示例 1

#![feature(scoped)]

use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};

pub fn foo<F>() {
    let mut join_guards = Vec::new();
    let value = AtomicUsize::new(0);

    for _ in 0..10 {
        join_guards.push(thread::scoped(|| {
            value.fetch_add(1, Ordering::SeqCst);
        }));
    }
}

示例 2

#![feature(scoped)]

use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering};

pub fn foo<F>(value: AtomicUsize) {
    let mut join_guards = Vec::new();

    for _ in 0..10 {
        join_guards.push(thread::scoped(|| {
            value.fetch_add(1, Ordering::SeqCst);
        }));
    }
}

这些是我在尝试编译示例 1 时收到的错误消息:

error: `value` does not live long enough
         join_guards.push(thread::scoped(|| {
             value.fetch_add(1, Ordering::SeqCst);
         }));
note: reference must be valid for the block at 6:20...
pub fn foo<F>() {
    let mut join_guards = Vec::new();
    let value = AtomicUsize::new(0);

     for _ in 0..10 {
         join_guards.push(thread::scoped(|| {

note: ...but borrowed value is only valid for the block suffix following statement 1 at 8:40
    let value = AtomicUsize::new(0);

     for _ in 0..10 {
         join_guards.push(thread::scoped(|| {
             value.fetch_add(1, Ordering::SeqCst);
         }));

join_guards 是具有特定共享生命周期的作用域线程向量。该生命周期由它关闭的变量决定:value 是唯一的一个。因此,scoped线程的生命周期是value的范围。 value 哪里合法? 在它被定义之后,直到它超出范围——也就是说,“8:40 处语句 1 之后的块后缀”。 join_guards的生命周期必须不超过这个,但是如果join_guards定义在之前 value,则不是这样。

解决办法是把声明的顺序倒过来:

let value = AtomicUsize::new(0);
let mut join_guards = Vec::new();

这也解释了为什么第二个示例也有效。