Rust 线程特征示例无法编译

问题描述 投票:0回答:2

我的例子几乎和发表在 https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fb2ac23ffc1e3a676df6a2add351d78c

但是我的没有编译消息

error[E0507]: cannot move out of index of `Vec<Box<dyn Process + Send>>`
  --> src/main.rs:35:19
   |
35 |             spawn(self.tasks[i], txi);
   |                   ^^^^^^^^^^^^^ move occurs because value has type `Box<dyn Process + Send>`, which does not implement the `Copy` trait
use std::sync::mpsc;
use std::sync::mpsc::Sender;
use std::thread;
use std::time;

trait Process {
    fn run(&mut self) -> String;
}

struct Runner {
    tasks: Vec<Box<dyn Process + Send>>,
}

fn spawn<T: ?Sized>(mut task: Box<T>, tx: Sender<String>)
where
    T: Process + Send + 'static,
{
    thread::spawn(move || {
        thread::sleep(time::Duration::from_secs(1));
        tx.send(format!("{:?}", task.run()))
    });
}

impl Runner {
    fn new() -> Self {
        Runner { tasks: Vec::new() }
    }
    fn subscribe(&mut self, p: Box<(dyn Process + Send)>) {
        self.tasks.push(p);
    }
    fn start(&mut self) {
        let (tx, rx) = mpsc::channel();
        for i in 0..self.tasks.len() {
            let txi = tx.clone();
            spawn(self.tasks[i], txi);
        }
        for r in rx {
            println!("Received : {:?}", r);
        }
    }
}

struct Foo {
    name: String,
    value: u32,
}
impl Foo {
    fn set_value(&mut self, v: u32) {
        self.value = v
    }
}
impl Process for Foo {
    fn run(&mut self) -> String {
        println!("Running {}", self.name);
        self.value = 33;
        println!("The value of {} is {}", self.name, self.value);
        self.name.clone()
    }
}

struct Bar {
    name: String,
    values: Vec<u32>,
}
impl Bar {
    fn new(nm: &str, sz: usize) -> Self {
        let array = Box::new(vec![0; sz]);
        let mut ret = Bar {
            name: nm.to_string(),
            values: *array,
        };
        for i in 0..sz {
            ret.write(i, 0);
        }
        ret
    }
    fn read(&mut self, addr: usize) -> u32 {
        self.values[addr]
    }
    fn write(&mut self, addr: usize, v: u32) {
        self.values[addr] = v;
    }
}
impl Process for Bar {
    fn run(&mut self) -> String {
        println!("Bar {} is sized {}", self.name, self.values.len());
        self.write(3, 42);
        println!("value 3 is {}", self.read(3));
        self.name.clone()
    }
}

fn main() {
    let mut r = Runner::new();
    let foo: Foo = Foo {
        name: "foo".to_string(),
        value: 0,
    };
    let bar: Bar = Bar::new("bar", 10);
    r.subscribe(Box::new(foo));
    r.subscribe(Box::new(bar));
    r.start();
}

我想了解其中的区别...

multithreading rust move traits
2个回答
0
投票

关于错误

错误解释:

error[E0507]: cannot move out of index of `Vec<Box<dyn Process + Send>>`

这与编译时遇到的错误相同:

let strings = vec![String::from("test")];

take_ownership(strings[0]); // error, because it moves `strings[0]` out of the `strings`

修复

参考这个例子,这可以通过克隆来修复,这样它就不会从向量中获取项目:

let strings = vec![String::from("test")];

take_ownership(strings[0].clone()); // no problem,
// because now a clone is passed into the function, and `strings[0]` stays in `strings`

或者使用可以复制的结构(实现

Copy

let strs = vec!["test"];

take_ownership(strs[0]);

应用到你的代码

克隆结构

// first, make sure that the item can be cloned by requiring the `Clone` trait
struct Runner {
    tasks: Vec<Box<dyn Process + Send + Clone>>,
}

// line 35
spawn(self.tasks[i].clone(), txi);

或者按照编译器的建议,impl

Copy
(不要认为它对你有用,因为
String
不 impl
Copy

希望这是清楚的


0
投票

感谢您的提示。解决方案

struct Runner {
    tasks: Vec<Box<dyn Process + Send + Clone>>,
}

不编译。最后,我得到了这个编译和运行

use std::thread;
use std::sync::mpsc::{Sender};
use std::sync::mpsc;
use std::time;

trait Process : CloneProcess {
    fn run(&mut self) -> String;
}

trait CloneProcess {
    fn clone_me<'a>(&self) -> Box<dyn Process + Send>;
}
impl<T> CloneProcess for T
where T: Process + Send + Clone + 'static,
{
    fn clone_me(&self) -> Box<dyn Process + Send> {
        Box::new(self.clone())
    }
}
impl Clone for Box<dyn Process + Send> {
    fn clone(&self) ->Self { self.clone_me()
    }
}
struct Runner {
    tasks: Vec<Box< dyn Process + Send>>,
    //    ready_queue: VecDeque<Arc<Mutex<dyn Process>>>,
    //   waiting_queue:VecDeque<Arc<Mutex<dyn Process>>>  ,
}

fn spawn<T: ?Sized>(mut bt : Box<T>, tx: Sender<String>)
where T: Process + Send + 'static,
{
    thread::spawn(move || {
        thread::sleep(time::Duration::from_secs(1));
        bt.run();
        tx.send("done".to_string()).unwrap();
    });
}

impl Runner{
    fn new() -> Self {
        Runner{tasks:Vec::new(),
               // ready_queue: VecDeque::new(),
               //      waiting_queue:VecDeque::new()
        }
    }
    fn subscribe(&mut self, p: Box<dyn Process + Send>)
    {
        self.tasks.push(p);
    }
    fn start(&mut self) {
        let (tx, rx) = mpsc::channel();
        for i in 0..self.tasks.len() {
            println!("spawning");
            let task = self.tasks[i].clone();
            spawn(task, tx.clone());
        };
        drop(tx);
        for r in rx {
            println!("Received : {:?}", r);
        };
    }
}

#[derive(Clone)]
struct Foo {
    name: String,
    value: u32,
}
impl Foo {
    fn set_value(&mut self, v: u32) {self.value = v }
}
impl Process for Foo {
    fn run(&mut self) -> String {
        self.set_value(33);
        println!("The value of {} is {}", self.name, self.value);
        self.name.clone()
    }
}
#[derive(Clone)]
struct Bar {
    name: String,
    values: Vec<u32>
}
impl Bar {
    fn new(nm: &str, sz: usize) -> Self{
        let array = Box::new(vec![0;sz]);
        let mut ret = Bar{ name:nm.to_string(),
                           values: *array
        };
        for i in 0..sz {
            ret.write(i, 0);
        }
        ret
    }
    fn read(&mut self, addr: usize) -> u32 {self.values[addr]}
    fn write(&mut self, addr: usize, v: u32) {self.values[addr]=v;}
}
impl Process for Bar {
    fn run(&mut self) -> String {
        println!("Bar {} is sized {}",
                 self.name,
                 self.values.len());
        self.write(3,42);
        println!("value 3 is {}", self.read(3));
        self.name.clone()
    }
}

fn main() {
    let mut r = Runner::new();
    let foo: Foo = Foo {
        name: "foo".to_string(),
        value: 0,
    };
    let bar: Bar = Bar::new("bar",10);
    r.subscribe(Box::new(foo));
    r.subscribe(Box::new(bar));
    r.start();
}
© www.soinside.com 2019 - 2024. All rights reserved.