Search code examples
rusttrait-objects

Is there a heapless trait object?


Is there a way to implement trait objects completely in stack memory?

This is the code that I use Box and thus heap memory:

extern crate alloc;
use alloc::vec::Vec;
use alloc::boxed::Box;
pub trait ConnectionImp {
    fn send_data(&self);
}

pub struct Collector {
    pub connections: Vec<Box<dyn ConnectionImp>>
}

impl Collector {
    pub fn new() -> Collector {
        Collector {
            connections: Vec::with_capacity(5),
        }
    }
    pub fn add_connection(&mut self,conn: Box<dyn ConnectionImp> ){
        self.connections.push(conn);
    }
}

I tried to use heapless crate but I could not find any replacement for Box. The following code shows the result of my effort:

use heapless::{Vec,/*pool::Box*/};
extern crate alloc;

use alloc::boxed::Box;

pub trait ConnectionImp {
    fn send_data(&self);
}

pub struct Collector {
    pub connections: Vec<Box<dyn ConnectionImp>,5>
}

impl Collector {
    pub fn new() -> Collector {
        Collector {
            connections: Vec::new(),
        }
    }

    pub fn add_connection(&mut self, conn: Box<dyn ConnectionImp> ){
        self.connections.push(conn);
    }
}

Solution

  • Yes, you can use &dyn Trait. A lot of examples of dynamic dispatch use Box because it's a more common use-case and using references introduces lifetimes, which tend to make examples more complicated.

    Your code would become:

    pub struct Collector<'a> {
        pub connections: Vec<&'a dyn ConnectionImp>,
    }
    
    impl<'a> Collector<'a> {
        pub fn new() -> Collector<'a> {
            Collector {
                connections: Vec::new(),
            }
        }
    
        pub fn add_connection(&mut self, conn: &'a dyn ConnectionImp) {
            self.connections.push(conn);
        }
    }