这类似于Parameter type may not live long enough?,但我对解决方案的解释似乎并不奏效。我最初的煮沸测试用例是:
use std::fmt::Debug;
use std::thread;
trait HasFeet: Debug + Send + Sync + Clone {}
#[derive(Debug, Clone)]
struct Person;
impl HasFeet for Person {}
#[derive(Debug, Copy, Clone)]
struct Cordwainer<A: HasFeet> {
shoes_for: A,
}
impl<A: HasFeet> Cordwainer<A> {
fn make_shoes(&self) {
let cloned = self.shoes_for.clone();
thread::spawn(move || {
println!("making shoes for = {:?}", cloned);
});
}
}
这给了我错误:
error[E0310]: the parameter type `A` may not live long enough
--> src/main.rs:19:9
|
16 | impl<A: HasFeet> Cordwainer<A> {
| -- help: consider adding an explicit lifetime bound `A: 'static`...
...
19 | thread::spawn(move || {
| ^^^^^^^^^^^^^
|
note: ...so that the type `[closure@src/main.rs:19:23: 21:10 cloned:A]` will meet its required lifetime bounds
--> src/main.rs:19:9
|
19 | thread::spawn(move || {
| ^^^^^^^^^^^^^
我没有进行A
'static
,而是为HasFeet
特征添加明确的生命周期:
use std::fmt::Debug;
use std::thread;
trait HasFeet<'a>: 'a + Send + Sync + Debug {}
#[derive(Debug, Copy, Clone)]
struct Person;
impl<'a> HasFeet<'a> for Person {}
struct Cordwainer<'a, A: HasFeet<'a>> {
shoes_for: A,
}
impl<'a, A: HasFeet<'a>> Cordwainer<'a, A> {
fn make_shoes(&self) {
let cloned = self.shoes_for.clone();
thread::spawn(move || {
println!("making shoes for = {:?}", cloned);
})
}
}
现在这给了我错误:
error[E0392]: parameter `'a` is never used
--> src/main.rs:11:19
|
11 | struct Cordwainer<'a, A: HasFeet<'a>> {
| ^^ unused type parameter
|
= help: consider removing `'a` or using a marker such as `std::marker::PhantomData`
我认为'a
用作HasFeet
特征的生命周期参数。我在这里做错了什么?
答案 0 :(得分:12)
std::thread::spawn()
函数声明其闭包时绑定了$Object = [];
foreach($array as $key => $val){
$Object[$key] = (object)$val;
}
print_r($Object);
。此闭包捕获的任何内容都必须满足Send + 'static
边界。在安全的Rust中有 no 方法。如果要使用此函数将数据传递给其他线程,则必须为Send + 'static
,句点。
可以使用正确的API解除'static
限制,有关示例,请参阅How can I pass a reference to a stack variable to a thread?。
然而,'static
界限并不像看起来那么可怕。首先,你不能强制任何东西做任何有生命界限的事情(你不能强制任何东西对任何类型的界限做任何事情)。 Bounds只是限制了可以用于有界类型参数的类型集合,这就是全部;如果你试图传递一个类型不满足这些边界的值,编译器将无法编译你的程序,它不会神奇地使值“活得更久”。
此外,'static
约束并不意味着该值必须在程序期间存在;这意味着该值不得包含带有'static
以外生命周期的借用引用。换句话说,它是值内可能引用的下限;如果没有引用,则绑定无关紧要。例如,'static
或String
或Vec<u64>
符合i32
边界。
'static
是一个非常自然的限制,可以放在'static
上。如果它不存在,则传递给另一个线程的值可能包含对父线程的堆栈帧的引用。如果父线程在生成的线程之前完成,则这些引用将变为悬空。