gpt4 book ai didi

rust - 参数类型可能不够长(使用线程)

转载 作者:行者123 更新时间:2023-11-29 07:49:20 26 4
gpt4 key购买 nike

这类似于 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 特征的生命周期参数。我在这里做错了什么?

最佳答案

std::thread::spawn() 函数声明为 Send + 'static约束其关闭。此闭包捕获的任何内容都必须满足 Send + 'static边界。在安全的 Rust 中没有解决这个问题。如果要使用该函数向其他线程传递数据,则必须是'static , 时期。

可以解除 'static使用适当的 API 进行限制,请参阅 How can I pass a reference to a stack variable to a thread?举个例子。

然而,一个'static束缚并不像看起来那么可怕。首先,你不能强制任何东西做任何有生命周期限制的事情(你不能强制任何东西做任何有任何种类限制的事情)。边界只是限制可用于有界类型参数的类型集,仅此而已;如果您尝试传递一个类型不满足这些界限的值,编译器将无法编译您的程序,它不会神奇地使这些值“生命周期更长”。

此外,一个 'static绑定(bind)并不意味着该值必须在程序的持续时间内存在;这意味着该值不能包含生命周期不是 'static 的借用引用.换句话说,它是值内部可能引用的下限;如果没有引用,则绑定(bind)无关紧要。例如,StringVec<u64>i32满足'static绑定(bind)。

'static是一个非常自然的限制 spawn() .如果它不存在,则传输到另一个线程的值可能包含对父线程堆栈帧的引用。如果父线程在派生线程之前完成,这些引用将变为悬空。

关于rust - 参数类型可能不够长(使用线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32083758/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com