Rust 向下转换后,模式匹配枚举与多个值时使用移动值
我可以对具有一个Rust 向下转换后,模式匹配枚举与多个值时使用移动值,rust,pattern-matching,Rust,Pattern Matching,我可以对具有一个字符串参数的枚举使用模式匹配: extern crate robots; use std::any::Any; use robots::actors::{Actor, ActorCell}; #[derive(Clone, PartialEq)] pub enum ExampleMessage { Msg { param_a: String }, } pub struct Dummy {} impl Actor for Dummy { // Using `
字符串
参数的枚举使用模式匹配:
extern crate robots;
use std::any::Any;
use robots::actors::{Actor, ActorCell};
#[derive(Clone, PartialEq)]
pub enum ExampleMessage {
Msg { param_a: String },
}
pub struct Dummy {}
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::Msg { param_a } => println!("got message"),
}
}
}
}
我以前在相同的enum
上尝试过模式匹配,但没有向下转换,这很好,但我需要向下转换。
这对我来说似乎是非常奇怪的行为,我不知道如何避免这个错误
我每晚使用Rust 1.19.0(afa1240e5 2017-04-29)
以前我在同一个枚举上尝试了模式匹配,但没有向下转换,效果很好
这是减少问题的一个很好的尝试。问题是你减少的太多了。将框
向下转换为Foo
不会返回Foo
,:
在这种情况下,您希望获得框中内容的所有权,以便在匹配中对其进行分解时获得字段的所有权。您可以通过在尝试匹配之前将值移出框来完成此操作
要做到这一点,还有很长的路要走:
fn receive2(message: Box<ExampleMessage>) {
let message = *message;
match message {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}
fn receive2(消息:框){
let message=*消息;
匹配消息{
示例消息::Msg{param_a,param_b}=>println!(“获取消息”),
}
}
但也可以使用大括号强制移动:
fn receive2(message: Box<ExampleMessage>) {
match {*message} {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}
fn receive2(消息:框){
匹配{*消息}{
示例消息::Msg{param_a,param_b}=>println!(“获取消息”),
}
}
我不完全理解为什么只有一个领域是可行的;这肯定是不一致的。我唯一的猜测是,框
的所有权被移动到第一个参数,参数被提取,然后编译器尝试再次将其移动到下一个参数
1-通过*
将包含的元素移出是一种特殊的功能,只有框
支持。例如,如果尝试使用引用执行此操作,则会出现“无法移出借用内容”错误。您也不能实现Deref
特性来实现这一点;这是编译器内部的硬编码功能
以前我在同一个枚举上尝试了模式匹配,但没有向下转换,效果很好
这是减少问题的一个很好的尝试。问题是你减少的太多了。将框
向下转换为Foo
不会返回Foo
,:
在这种情况下,您希望获得框中内容的所有权,以便在匹配中对其进行分解时获得字段的所有权。您可以通过在尝试匹配之前将值移出框来完成此操作
要做到这一点,还有很长的路要走:
fn receive2(message: Box<ExampleMessage>) {
let message = *message;
match message {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}
fn receive2(消息:框){
let message=*消息;
匹配消息{
示例消息::Msg{param_a,param_b}=>println!(“获取消息”),
}
}
但也可以使用大括号强制移动:
fn receive2(message: Box<ExampleMessage>) {
match {*message} {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}
fn receive2(消息:框){
匹配{*消息}{
示例消息::Msg{param_a,param_b}=>println!(“获取消息”),
}
}
我不完全理解为什么只有一个领域是可行的;这肯定是不一致的。我唯一的猜测是,框
的所有权被移动到第一个参数,参数被提取,然后编译器尝试再次将其移动到下一个参数
1-通过*
将包含的元素移出是一种特殊的功能,只有框
支持。例如,如果尝试使用引用执行此操作,则会出现“无法移出借用内容”错误。您也不能实现Deref
特性来实现这一点;这是编译器内部的一种硬编码功能。我在这里很难修复我的心智模型……您的原始版本的receive2
有什么问题?为什么只绑定单个结构字段时问题就消失了?这与盒子的特殊性有关吗?还有,你指的是什么特殊力量?谢谢Shep@user1935361我添加了更多的文本。关于[1]——因为Deref
总是返回一个引用,我想我明白了。我在这里很难修正我的心智模型……你原来版本的receive2
有什么问题?为什么只绑定单个结构字段时问题就消失了?这与盒子的特殊性有关吗?还有,你指的是什么特殊力量?谢谢Shep@user1935361我添加了更多的文本。关于[1]——因为Deref
总是返回一个引用,我想我明白了。
enum Foo {
One,
Two,
}
fn main() {
let f = &Foo::One;
match *f {
Foo::One => {}
Foo::Two => {}
}
}
fn receive2(message: Box<ExampleMessage>) {
let message = *message;
match message {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}
fn receive2(message: Box<ExampleMessage>) {
match {*message} {
ExampleMessage::Msg { param_a, param_b } => println!("got message"),
}
}