模式匹配后保存 Vec
Save Vec after pattern match
我正在使用机器人箱中的 Actor
特性:
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
以后可以访问它.
您在这里遗漏了一个简单的要点:您的方法 receive()
获取 &self
作为参数。您不能通过 &self
修改 self
对象,因为它是一个 immutable 引用。为了更改 self
的任何字段,接受可变引用 (&mut self
) 或——如果没有办法绕过它——使用内部可变性。示例:
fn receive(&mut self, message: Box<Any>) {
// ...
self.data = data; // works
// ...
}
但是,如果您不能更改 Dummy
实现的特征 Actor
,那么这在您的情况下可能是不可能的。在这种情况下,您 必须 使用 interior mutability,例如RefCell<Vec<u8>>
。但如果你能改变这个特质,考虑这样做。方法 receive()
已经听起来像 self
对象应该被更改以产生任何效果。
如果这不仅仅是您的粗心错误,请务必阅读 Rust 书中有关 Borrowing and Mutability 的章节,因为这对 Rust 非常重要。
我在 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 }
}
}
我正在使用机器人箱中的 Actor
特性:
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
以后可以访问它.
您在这里遗漏了一个简单的要点:您的方法 receive()
获取 &self
作为参数。您不能通过 &self
修改 self
对象,因为它是一个 immutable 引用。为了更改 self
的任何字段,接受可变引用 (&mut self
) 或——如果没有办法绕过它——使用内部可变性。示例:
fn receive(&mut self, message: Box<Any>) {
// ...
self.data = data; // works
// ...
}
但是,如果您不能更改 Dummy
实现的特征 Actor
,那么这在您的情况下可能是不可能的。在这种情况下,您 必须 使用 interior mutability,例如RefCell<Vec<u8>>
。但如果你能改变这个特质,考虑这样做。方法 receive()
已经听起来像 self
对象应该被更改以产生任何效果。
如果这不仅仅是您的粗心错误,请务必阅读 Rust 书中有关 Borrowing and Mutability 的章节,因为这对 Rust 非常重要。
我在 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 }
}
}