我对 Rust 的生命周期有点挣扎:
为什么 run_trait_test
需要 'static
生命周期?
我希望它的行为像run_concrete_test
我阅读了文档,搜索了 stackoverflow 和 rust-book,但我显然遗漏了一些东西。
use std::thread;
#[derive(Debug, Clone)]
struct Test {
test_string: String,
}
trait Example {
fn tst(&self) -> ();
}
impl Example for Test {
fn tst(&self) {
println!("{:?}", self);
}
}
// compiles, no 'static here
fn run_concrete_test(tester: &Test) {
let t = tester.clone();
thread::spawn(move || {
t.tst();
});
}
// compiles with 'static
// but F shouldn't be only static
fn run_trait_test<F>(tester: &'static F)
where
F: Example + Sync + Send + 'static,
{
let t = tester.clone();
let store_t = thread::spawn(move || {
t.tst();
});
}
fn main() {
//does run, no static
let x = Test {
test_string: "test string".to_string(),
};
run_concrete_test(&x);
// doe sn't compile because of static
// run_trait_test(&x);
println!("{:?}", x);
}
最佳答案
The following traits are implemented for all &T, regardless of the type of its referent:
- ...
- Clone (Note that this will not defer to T's Clone implementation if it exists!)
- ...
由于 F
具有 'static
生命周期边界,因此 &F
是一种共享变量:
- 如果没有
Clone
边界,编译器将使用借用的clone
F
的版本(简单来说,它只是克隆引用) - 有了
Clone
边界,编译器将使用F
的Clone
的实现
有了所有这些,下面的代码将与 run_concrete_test
一样工作:
trait Example {
fn test(&self);
}
fn _run_trait_test<F>(tester: &F)
where
F: Example + Sync + Send + Clone + 'static,
{
let t = tester.clone();
::std::thread::spawn(move || {
t.test();
});
}
注意:如果没有'static
生命周期边界,F
可能会被视为某些T
' s 借用类型,如 F = &T
关于rust - 为什么“通过克隆拥有的变量需要静态生命周期”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56336526/