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

标签 rust

这类似于 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/54436058/

相关文章:

error-handling - 如何处理 Read::read_to_end 方法的错误?

compiler-errors - Rust:奇怪的错误 "` Slice` 不是特征”

ios - 在 iOS 应用程序中添加多个静态 Rust 库

rust - 无法移出 Rust 中的借用内容

c - 如何在不更改构建系统的情况下在 C 项目中使用 Rust 代码?

generics - 不安全队列实现

rust - 为什么我的变量在调试时会重复并且有时会损坏?

rust - 如何使用rust "use another-file"?带有连字符的模块

rust - 为什么编译器报告错误的部分移动而不是移动?

rust - 如何在 Rust 的内循环中正确移动所有权?