rust - 可以在 Rust 中使用泛型类型的 trait 对象吗?
问题描述
我对如何使用 Rust 的特征对象感到困惑。我有很多模糊的部分理解,但最后我不明白我得到的错误。
我正在尝试在 rust 中实现命令模式,以便在终端周围移动光标。我将其设置为发送实现 Command 特征的特征对象,并具有通用类型的 Command 特征。我不能让这个特征通用吗?
这是我的代码的示例版本:
pub trait Command<T> {
fn execute(&self, target_instance: &mut T);
}
pub trait Commandable<T> {
fn send(&mut self, cmd: Box<impl Command<T>>);
}
//-------------------------------------------------------
struct Cursor {
pos: (isize, isize),
}
impl Cursor {
fn move_me(&mut self, direction: (isize, isize)) {
self.pos.0 += direction.0;
self.pos.1 += direction.1;
}
}
impl Commandable<Cursor> for Cursor {
fn send(&mut self, cmd: Box<impl Command<Cursor>>) {
cmd.execute(self);
}
}
struct MoveCommand {
move_direction: (isize, isize),
}
impl MoveCommand {
pub fn new(move_direction: (isize, isize)) -> Self {
MoveCommand { move_direction }
}
}
impl Command<Cursor> for MoveCommand {
fn execute(&self, cursor: &mut Cursor) {
cursor.move_me(self.move_direction);
}
}
//------------------------------------------------------
fn handle_input(input: Option<&str>, target: &mut impl Commandable<Cursor>) {
let mut cmd: Option<Box<dyn Command<Cursor>>> = None;
if let Some(key) = input {
match key {
"K" => cmd = Some(Box::new(MoveCommand::new( (0, -1) ))),
"J" => cmd = Some(Box::new(MoveCommand::new( (0, 1) ))),
"H" => cmd = Some(Box::new(MoveCommand::new( (-1, 0) ))),
"L" => cmd = Some(Box::new(MoveCommand::new( (1, 0) ))),
_ => {}
}
}
if let Some(boxed_cmd) = cmd {
target.send(boxed_cmd); // <-----------------ERROR IS HERE
}
}
fn main() {
let mut cursor = Cursor { pos: (0, 0) };
handle_input(Some("K"), &mut cursor);
}
这是错误:
error[E0277]: the size for values of type `dyn Command<Cursor>` cannot be known at compilation time
--> src/main.rs:54:21
|
54 | target.send(boxed_cmd);
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Command<Cursor>`
解决方案
回答我自己的问题以帮助未来的人们:
我的主要问题是我不明白 和 之间的dyn MyTraitObj
区别impl MyTraitObj
。impl
我交替使用它们,所以一旦我将所有的'交换为dyn
',我发布的代码就会编译。
@LeoVen 链接了这个,这解决了我的困惑:当用作方法参数时,trait 和 impl trait 有什么区别?
感谢所有提供帮助的人。
推荐阅读
- c# - c# [OnPrem CRM] 中的 Dynamics crm retrieveEntityReq (Javascript) 函数
- squid - 带有 SSLbump 和身份验证 403 的 Squid。这是一个封装的请求,不进行身份验证
- ios - 无法设置收集单元
- angular - ng2-chart 仅在光标位于某个位置时刷新
- selenium - Nightwatch 没有获取 sendkeys 值
- xml - 使用 XSLT 提取和更新 XML
- android - 在基于 MVVM 的应用程序中添加 Room Database 类会产生绑定问题
- ruby-on-rails - 如何在 Active Storage 中仅存储 .yml 文件
- java - 变量是从内部类中访问的,需要声明为final
- sql - Oracle Apex:根据条件在报告中创建红绿灯