2015-06-16 109 views
3

我試圖讓內不變值這個例子中工作閱讀產生的線程

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 

現在根據this discussion它應該有工作,但它不」噸。我在這裏錯過了什麼?

回答

5

你快到了。這只是Arc已被克隆外產生的線程的

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確實將被轉移到該線程,並在一個循環中這樣做是違反所有權規則。