2015-09-26 28 views
0

正如标题已经说过的,我试图将一个&[&str]移动到一个线程中。嗯,其实,下面的代码工作,但我有两个问题是:将一个&[&str]移动到一个线程

  1. let args2: Vec<_> = args.iter().map(|arg| { arg.to_string() }).collect();似乎有点冗长的&[&str]转换为Vec<String>。这可以做到“更好”吗?
  2. 如果我理解正确,字符串会被复制两次:第一个是let cmd2let args2语句;然后通过在move关闭内移动它们。它是否正确?如果是这样,可以用一个副本来完成吗?

我所知道的thread::scoped,不过目前已被弃用。我也在编写这个代码来学习一些关于Rust的知识,所以关于“不可信”代码的评论也是值得赞赏的。

use std::process::{Command,Output}; 
use std::thread; 
use std::thread::JoinHandle; 

pub struct Process { 
    joiner: JoinHandle<Output>, 
} 

impl Process { 
    pub fn new(cmd: &str, args: &[&str]) -> Process { 
     // Copy the strings for the thread 
     let cmd2 = cmd.to_string(); 
     let args2: Vec<_> = args.iter().map(|arg| { arg.to_string() }).collect(); 

     let child = thread::spawn(move || { 
      Command::new(cmd2).args(&args2[..]).output().unwrap_or_else(|e| { 
       panic!("Failed to execute process: {}", e) 
      }) 
     }); 
     Process { joiner: child } 
    } 
} 

回答

3

let args2: Vec<_> = args.iter().map(|arg| { arg.to_string() }).collect();似乎有点冗长转换一个& [& STR]到A VEC。这可以做到“更好”吗?

我不这么认为。有一些小的变化也可以工作(例如args.iter().cloned().map(String::from).collect();),但我想不出一个更好的。一个小问题是,使用to_string&str转换为String的效率不如使用String::fromto_owned

如果我理解正确的话,琴弦被复制两次:第一次由设CMD2,让args2报表;然后通过将它们移动到移动闭合内部。它是否正确?如果是这样,可以用一个副本来完成吗?

不,字符串只在您拨打to_string的地方复制。字符串不实现Copy,所以它们不会被隐式复制。如果您尝试在移动到闭包后访问这些字符串,则会出现编译器错误。

+0

谢谢你'String :: from'。对于第二点,我首先明确地将字符串复制到'cmd2'和'args2'中,但是当它们被移入闭包时,它们是不是也被物理地复制到了线程堆栈中呢? – Garogolun

+0

@Garogolun那么,矢量被复制,但这只是一个浅拷贝(即包含指针,长度和容量的结构)。矢量的内容不被复制。 – fjh

+0

线程可以访问向量的内容。但是,如果'Process :: new'返回,则矢量及其内容会被破坏。那么这不是不安全吗? – Garogolun

相关问题