读取生成线程内的不可变值

2023-12-03

我正在努力让这个例子发挥作用

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

struct User {
    reference: String,
    email: String
}

struct UserIndex {
    reference: usize,
    email: usize
}

fn main() {

    let rows = vec![
        vec!["abcd", "[email protected]"],
        vec!["efgh", "[email protected]"],
        vec!["wfee", "[email protected]"],
        vec!["rrgr", "[email protected]"]
    ];

    let user_index = Arc::new(
        UserIndex {
            reference: 0,
            email: 1
        }
    );

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

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

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

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

}

但它抛出一个错误

src/main.rs:43:28: 43:38 error: capture of moved value: `user_index` [E0382]
src/main.rs:43          let user_index_cloned = user_index.clone();
                                                ^~~~~~~~~~
note: in expansion of closure expansion
src/main.rs:42:17: 51:4 note: expansion site
note: in expansion of for loop expansion
src/main.rs:40:2: 52:3 note: expansion site
src/main.rs:42:17: 51:4 note: `user_index` moved into closure environment here because it has type `[closure(())]`, which is non-copyable
src/main.rs:42      thread::spawn(move || {
src/main.rs:43          let user_index_cloned = user_index.clone();
src/main.rs:44          let result = chunk.iter().map( |row|
src/main.rs:45              User {
src/main.rs:46                  reference: row[user_index_cloned.reference].to_string(),
src/main.rs:47                  email: row[user_index_cloned.email].to_string()
               ...
note: in expansion of closure expansion
src/main.rs:42:17: 51:4 note: expansion site
note: in expansion of for loop expansion
src/main.rs:40:2: 52:3 note: expansion site
src/main.rs:42:17: 51:4 help: perhaps you meant to use `clone()`?
error: aborting due to previous error

现在根据这次讨论它应该有效,但没有。我在这里缺少什么?


你快到了。只是这样Arc必须被克隆outside生成的线程的:

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

必须这样做,否则user_index确实会被移动到线程中,并且在循环中执行此操作违反了所有权规则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读取生成线程内的不可变值 的相关文章

随机推荐