跨多个线程使用 Chunks 迭代器时,值的存活时间不够长

Cab*_*ero 4 rust

这是我的情况的简化示例:

use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

struct User {
    reference: String,
    email: String,
}

fn main() {
    let rows = vec![
        vec!["abcd", "test@test.com"],
        vec!["efgh", "test1@test.com"],
        vec!["wfee", "test2@test.com"],
        vec!["rrgr", "test3@test.com"],
    ];

    let chunk_len = (rows.len() / 2) as usize;
    let mut chunks = Vec::new();
    for chunk in rows.chunks(chunk_len) {
        chunks.push(chunk);
    }

    let (tx, rx): (Sender<Vec<User>>, Receiver<Vec<User>>) = mpsc::channel();

    for chunk in chunks {
        let thread_tx = tx.clone();
        thread::spawn(move || {
            let result = chunk
                .iter()
                .map(|row| {
                    User {
                        reference: row[0].to_string(),
                        email: row[1].to_string(),
                    }
                })
                .collect::<Vec<User>>();
            thread_tx.send(result).unwrap();
        });
    }

    let mut users = Vec::new();
    for _ in 0..chunk_len {
        users.push(rx.recv());
    }
}
Run Code Online (Sandbox Code Playgroud)

它抛出了一个错误

use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

struct User {
    reference: String,
    email: String,
}

fn main() {
    let rows = vec![
        vec!["abcd", "test@test.com"],
        vec!["efgh", "test1@test.com"],
        vec!["wfee", "test2@test.com"],
        vec!["rrgr", "test3@test.com"],
    ];

    let chunk_len = (rows.len() / 2) as usize;
    let mut chunks = Vec::new();
    for chunk in rows.chunks(chunk_len) {
        chunks.push(chunk);
    }

    let (tx, rx): (Sender<Vec<User>>, Receiver<Vec<User>>) = mpsc::channel();

    for chunk in chunks {
        let thread_tx = tx.clone();
        thread::spawn(move || {
            let result = chunk
                .iter()
                .map(|row| {
                    User {
                        reference: row[0].to_string(),
                        email: row[1].to_string(),
                    }
                })
                .collect::<Vec<User>>();
            thread_tx.send(result).unwrap();
        });
    }

    let mut users = Vec::new();
    for _ in 0..chunk_len {
        users.push(rx.recv());
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试更改为,chunks.push(chunk.clone());但错误仍然不会消失。我在这里缺少什么?

Vla*_*eev 5

该错误看起来确实具有误导性,但它是正确的。您的问题实际上是将切片chunks()的迭代器提供给原始向量:

impl<'a, T> Iterator for Chunks<'a, T> {
    type Item = &'a [T];
}
Run Code Online (Sandbox Code Playgroud)

您正在尝试在spawn()需要闭包具有'static生命周期的ed 线程中使用此切片:

pub fn spawn<F, T>(f: F) -> JoinHandle<T> 
where
    F: FnOnce() -> T,
    F: Send + 'static,
    T: Send + 'static, 
Run Code Online (Sandbox Code Playgroud)

您的迭代器确实具有'static生命周期,因为它包含对运行时分配向量的引用。

你说你试过clone(),但这只克隆了切片,它不会给你一个新的载体。为此,您需要使用to_owned()

for chunk in rows.chunks(chunk_len) {
    chunks.push(chunk.to_owned());
}
Run Code Online (Sandbox Code Playgroud)

瞧,它编译