1

I have some structs like:

pub struct A {}

pub struct B {}

I want to map these structs to a string mapping:

let s = match x {
    "a" => A {},
    "b" => B {},
    _ => panic!()
} 

like a Python dict. How can I do this in Rust?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Manish Gupta
  • 4,438
  • 18
  • 57
  • 104
  • You can do [matching on strings](https://stackoverflow.com/questions/25383488/how-to-match-a-string-against-string-literals-in-rust), but that's not at all "like a python dict". What you seem to need is a [hashmap](https://doc.rust-lang.org/std/collections/struct.HashMap.html). – Denys Séguret Oct 01 '19 at 09:14
  • If those links don't answer your problem, please explain your need and build a [MCVE]. – Denys Séguret Oct 01 '19 at 09:16
  • 3
    Note that rust is a strongly typed language. Your code sample can hardly make sense. – Denys Séguret Oct 01 '19 at 09:22
  • Do you want to store some created struct to a dictionary and then retrieve them from it? Or you just want to create and return these struct like you share on the question? – Akiner Alkan Oct 01 '19 at 10:16

1 Answers1

5

Rust is not like Python. In Rust, you have to know the size of all your objects on the stack at compile time. If not, then you have to use dynamic objects that are allocated on the heap.

In C++ or similar languages, you'd create a base class where both your classes inherit from it. This way, you can dynamically create an object at run-time, with a type that you choose based on a run-time condition. This is the classical way of doing things.

In Rust, the alternative is called "trait objects", where both your classes implement the same trait (so that trait plays the role of a base class). Here's how you do it:

trait C {}

impl C for A {}

impl C for B {}

pub struct A {}

pub struct B {}

fn main() {
    println!("Hello, world!");
    let x = "a";
    let s: Box<dyn C> = match x {
        "a" => Box::new(A {}),
        "b" => Box::new(B {}),
        _ => panic!()
    };
}

Box is a safe container for a pointer, which will be deallocated when you exit this scope (unless you choose to pass it somewhere else).

Play with this code on playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • I agree that this is a good way to do it. However, sometimes you can avoid `Box`ing the value (e.g. if you pass it directly to a function). For those cases, I came up with an ugly macro (see https://stackoverflow.com/a/55249378/255688) that can dispatching using different types. – phimuemue Oct 03 '19 at 09:58