Is it possible to pass a reference to an uninitialised struct?

I want to create an array of unitialised structs based on a specific trait so that I can do something progromatically.

But I cant work out how to do it or if its possible.

trait Foo {
    const NAME: &'static str;
    fn new() -> Self;
    fn name(&self) -> &'static str {

struct Bar {}

impl Foo for Bar {
    const NAME: &'static str = "Bar";

    fn new() -> Self {
        Self {}

struct Baz {}

impl Foo for Baz {
    const NAME: &'static str = "Baz";

    fn new() -> Self {
        Self {}

fn main() {
    let structs = [Bar, Baz];
    for s in structs{
        let inst = s::new();


What you are trying to achieve is possible, but you might need to structure it slightly differently.

The code you've written tries to treat a struct's name as some sort of object that can be passed around and used to construct the type dynamically, similar to the java.lang.Class in Java or the name of a class in Python.

Rust deliberately doesn't have a reflection system which knows how to construct objects at runtime, so we kinda need to implement it ourselves. This isn't as hard as it sounds.

What I would do is store a list of functions that can be used to construct these values, and make sure the function returns a value who's type is erased at runtime. Normally you can't store a Baz and a Bar in the same slice because they have different types with possibly different sizes, so it's important to add some level of indirection to "forget" the actual size/type of Bar and Baz (i.e. Box<dyn Foo>).

First, let's modify the Foo trait so it is "object safe". In order to erase the type at runtime, your trait can't have any methods which would require knowing a value's actual type, so things like associated constants/types (they're associated with your type) or methods that accept/return Self by value (the compiler would need to know the value's type in order to allocate the right amount of stack space for variables) are out.

trait Foo {
  fn name(&self) -> &'static str;

struct Bar;
impl Foo for Bar { fn name(&self) -> &'static str { "Bar" } }

struct Baz;
impl Foo for Baz { fn name(&self) -> &'static str { "Baz" } }

Next, we add our constructor functions to the structs array.

type FooConstructor = fn() -> Box<dyn Foo>;

let structs: [FooConstructor; 2] = [
    || Box::new(Bar),
    || Box::new(Baz),

And now we can iterate through the constructors, and create instances of our Foo type.

for s in structs {
    let instance: Box<dyn Foo> = s();


This way of passing around a closure to "defer" an object's construction can be particularly useful when you are making some sort of "factory" that will pick and choose which Foo implementation to construct at runtime.


This has helped me a lot thank you! I was thinking something along the lines of Box might need to be used, but I had no idea how....

I cut my teeth on Python, so that probably explains my thinking!

1 Like