繁体   English   中英

如何使 Rust 通用结构/特征需要一个 Box<other trait> ?

[英]How to make a Rust Generic Struct/Trait require a Box<other trait>?

我有一个代表模拟中的代理的 trait Agent ,以及一个实现这个 trait 的 struct SimpleAgent 由于在编译时不知道Agent的大小,我的代码通常使用Vec<Box<dyn Agent>>我想创建一个通用特征AgentCollection<T>并用AgentTree<T>结构实现它。

到目前为止,我有以下几点:

pub trait AgentCollection<T> {
    fn new(agents: Vec<Box<T>>) -> Self;
    fn get_in_rectilinear_range(point: vec::Vec2, range: f64) -> Vec<Box<T>>;
    fn get_in_euclidean_range(point: vec::Vec2, range: f64) -> Vec<Box<T>>;
}

pub struct AgentTree<T: agent::Agent> {
    left: Option<Box<AgentTree<T>>>,
    right: Option<Box<AgentTree<T>>>,
    node: Box<T>,
}

#[allow(unused)]
impl<T: agent::Agent> AgentTree<T> {
    fn range_search(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }
}

impl<T: agent::Agent> AgentCollection<T> for AgentTree<T> {
    fn new(agents: std::vec::Vec<Box<T>>) -> Self {
        todo!()
    }

    fn get_in_rectilinear_range(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }

    fn get_in_euclidean_range(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }
}

这都是类型检查。 但是,当我在主文件中使用它时,例如

let agent_tree = AgentTree::new(last_agents);

其中last_agents类型为std::vec::Vec<std::boxed::Box<dyn agent::Agent>> ,我收到错误the size for values of type 'dyn agent::Agent' cannot be known at compilation time

我想我想以某种方式将AgentTree类型参数限制为Box<agent::Agent而不仅仅是agent::Agent ,以便它的大小,但我不知道如何做到这一点。 例如,我尝试过: pub struct AgentTree<T: Box<agent::Agent>> { ... }

想通了,我添加了以下内容:

type BoxedAgent = Box<dyn agent::Agent>;

然后使用BoxedAgent代替Box<T: agent::Agent>

如果有人有更好的建议,我会暂时打开它。

默认情况下,泛型类型参数将有一个Sized trait bound,它需要一个 sized 类型。 但是像dyn Agent这样的 trait 对象没有大小,它们可以表示多种类型,因此在编译时无法知道它们的大小。

为了让你的代码与dyn Agent一起工作,你所要做的就是在你的 trait bound 中添加?Sized以删除默认的Sized trait bound:

pub trait AgentCollection<T: ?Sized> {
//                           ^^^^^^
    fn new(agents: Vec<Box<T>>) -> Self;
    fn get_in_rectilinear_range(point: vec::Vec2, range: f64) -> Vec<Box<T>>;
    fn get_in_euclidean_range(point: vec::Vec2, range: f64) -> Vec<Box<T>>;
}

pub struct AgentTree<T: ?Sized + agent::Agent> {
//                      ^^^^^^
    left: Option<Box<AgentTree<T>>>,
    right: Option<Box<AgentTree<T>>>,
    node: Box<T>,
}

#[allow(unused)]
impl<T: ?Sized + agent::Agent> AgentTree<T> {
//      ^^^^^^
    fn range_search(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }
}

impl<T: ?Sized + agent::Agent> AgentCollection<T> for AgentTree<T> {
//      ^^^^^^
    fn new(agents: std::vec::Vec<Box<T>>) -> Self {
        todo!()
    }

    fn get_in_rectilinear_range(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }

    fn get_in_euclidean_range(point: vec::Vec2, range: f64) -> std::vec::Vec<Box<T>> {
        todo!()
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM