Arc::clone 的结果怎么会有“静态生命周期”?

How could the result of Arc::clone have a 'static lifetime?

让我们从 Arc

的典型示例开始
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let msg = Arc::new(Mutex::new(String::new()));
    let mut handles = Vec::new();
    for _ in 1..10 {
        let local_msg = Arc::clone(&msg);
        handles.push(thread::spawn(move || {
            let mut locked = local_msg.lock().unwrap();
            locked.push_str("hello, world\n");
        }));
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", msg.lock().unwrap());
}

这会按预期编译和运行。然后我意识到也许 Mutex 不必存在于堆上并开始想知道我是否可以摆脱 Arc 并只使用对分配在堆栈上的 Mutex 的共享引用.这是我的尝试

use std::sync::Mutex;
use std::thread;

fn main() {
    let msg = Mutex::new(String::new());
    let mut handles = Vec::new();
    for _ in 1..10 {
        let local_msg = &msg;
        handles.push(thread::spawn(move || {
            let mut locked = local_msg.lock().unwrap();
            locked.push_str("hello, world\n");
        }));
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("{}", msg.lock().unwrap());
}

虽然这个不能编译

error[E0597]: `msg` does not live long enough
  --> src/main.rs:8:25
   |
8  |           let local_msg = &msg;
   |                           ^^^^ borrowed value does not live long enough
9  |           handles.push(thread::spawn(move || {
   |  ______________________-
10 | |             let mut locked = local_msg.lock().unwrap();
11 | |             locked.push_str("hello, world\n");
12 | |         }));
   | |__________- argument requires that `msg` is borrowed for `'static`
...
20 |   }
   |   - `msg` dropped here while still borrowed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `hello`

To learn more, run the command again with --verbose.

编译器抱怨 local_msg 没有 'static 生命周期。嗯,它没有,所以这个错误是有道理的。但是,这意味着第一个片段中的变量 let local_msg = Arc::clone(&msg); 具有 'static 生命周期,否则我应该会得到类似的错误。

问题:

编译器正在寻找的东西是生命周期绑定。生命周期绑定'a并不意味着“此类型是生命周期[=的引用10=]”,而是“该类型包含的所有引用的生命周期至少为 'a”。

(显式写入生命周期时,它看起来像 where T: 'a。)

因此,任何 不包含 任何引用(或者更确切地说,没有生命周期参数)的类型都会自动满足 'static 生命周期界限。如果 T: 'static,则 Arc<T>: 'staticBoxRc 也是如此)。

How could Arc::clone(&msg) get a 'static lifetime? The value it points to isn't known at compile-time, and could die before the whole program exits.

它没有使用引用指向值,所以没问题。你的值的类型是Arc<Mutex<String>>;这里没有生命周期参数,因为没有引用。如果假设是 Arc<'a, Mutex<String>>Arc 实际上没有的生命周期参数),那么该类型将不满足界限。

Arc(或RcBox)的工作是拥有它指向的值。所有权不是参考,因此不受生命周期限制。

但是,如果您有 Arc<Mutex<&'a str>> 类型,那么它不会满足边界,因为它 包含一个引用 而不是 'static