2017-05-02 57 views
0

我使用Actor特質從機器人箱子:保存VEC後,模式匹配

extern crate robots;  

use std::any::Any; 
use robots::actors::{Actor, ActorCell}; 


#[derive(Clone, PartialEq)] 
pub enum ExampleMessage { 
    Test { data: Vec<u8> }, 
} 

pub struct Dummy { 
    data: Vec<u8>, 
} 

impl Actor for Dummy { 
    // Using `Any` is required for actors in RobotS 
    fn receive(&self, message: Box<Any>, _context: ActorCell) { 
     if let Ok(message) = Box::<Any>::downcast::<ExampleMessage>(message) { 
      match *message { 
       ExampleMessage::Test { data } => { 
        self.data = data; // cannot assign to immutable field 
        println!("got message") 
       } 
      } 
     } 
    } 
} 

impl Dummy { 
    pub fn new(_:()) -> Dummy { 
     let data = Vec::new(); 
     Dummy { data } 
    } 
} 

錯誤:

error: cannot assign to immutable field `self.data` 
    --> <anon>:18:21 
    | 
18 |      self.data = data; // cannot assign to immutable field 
    |      ^^^^^^^^^^^^^^^^ 

我明白爲什麼我當前的代碼不工作,但我不」不知道保存傳入數據的最佳方法是什麼(Vec),以便我的Dummy可以稍後訪問它。

回答

0

我在RobotS github庫中發現了一個test,它顯示瞭如何管理Actor的內部狀態。 州有Mutex裏面被封裝爲線程安全的訪問:

extern crate robots;  

use std::any::Any; 
use std::sync::Mutex; 
use robots::actors::{Actor, ActorCell}; 


#[derive(Clone, PartialEq)] 
pub enum ExampleMessage { 
    Test { data: Vec<u8> }, 
} 

pub struct Dummy { 
    data: Mutex<Vec<u8>>, 
} 

impl Actor for Dummy { 
    // Using `Any` is required for actors in RobotS 
    fn receive(&self, message: Box<Any>, _context: ActorCell) { 
     if let Ok(message) = Box::<Any>::downcast::<ExampleMessage>(message) { 
      match *message { 
       ExampleMessage::Test { data } => { 
        let mut my_data = self.data.lock().unwrap(); 
        *my_data = data; 
        println!("got message") 
       } 
      } 
     } 
    } 
} 

impl Dummy { 
    pub fn new(_:()) -> Dummy { 
     let data = Mutex::new(Vec::new()); 
     Dummy { data } 
    } 
} 
1

您缺少一個簡單的點:您的方法得到&self作爲參數。您不能通過&self修改self對象,因爲它是不可變的參考。爲了改變self的任何字段,請接受一個可變參考(&mut self)或 - 如果沒有辦法繞過它 - 請使用內部可變性。例如:

fn receive(&mut self, message: Box<Any>) { 
    // ... 
    self.data = data; // works 
    // ... 
} 

但是,這也許是不可能的,你的情況,如果你不能改變的特質ActorDummy工具。在這種情況下,您的已使用來使用interior mutability,例如, RefCell<Vec<u8>>。但如果你能改變這個特質,那就考慮這樣做。方法已經聽起來像self對象應該被改變以產生任何效果。

如果這不僅僅是一個粗心的錯誤,請務必閱讀Rust書中BorrowingMutability的章節,因爲這對Rust非常重要。

+0

我實現了Dummy'的演員特質'IMPL演員。因爲我正在實現這個特性,所以我不能使引用可變,因爲這會導致不兼容的類型錯誤。 – Anton

+0

@Anton看我的編輯。 –

+0

我無法使用RefCell,因爲它不符合特徵綁定的'std :: marker :: Sync'。我在github的機器人回購中發現了一個[測試](https://github.com/gamazeps/RobotS/blob/master/test/test.rs)。我必須使用Mutex,我會在今天晚些時候寫出答案。 – Anton