5

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);
    }
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
p3zhy
  • 81
  • 8

1 Answers1

7

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);
    }
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204