1

Is it possible to get a value from a struct using a string key? Like this:

struct Messages {
    greetings: String,
    goodbyes: String
}

impl Structure {
    fn new() -> Structure{
        Messages {
            greetings: String::from("Hello world"),
            goodbyes: String::from("Bye!")
    }
}

fn main() {
    let messages = Messages::new();
    // now how do I print it out with a string key?
    println!("{}",messages["greetings"]); // prints "Hello world"

    // and can I even turn a struct into an array? Function name is made up
    let arr = Struct::to_array(messages);
}

Pls help thz

6
  • no, it;s not possible. What are you trying to achieve ? Commented Oct 12, 2021 at 16:54
  • loop through a structure to print it out in a tic tac toe format (I'm still learning rust) I'm doing a 9x9 tictactoe board so it is gonna be painful to type everything out (I stored data in 0,1 and 2) Commented Oct 12, 2021 at 16:57
  • 1
    What you are asking is possible but I doubt that a new rust learner would require such a workaround. For your question, you can see Index trait and you can automate its generation by macros. Commented Oct 12, 2021 at 17:02
  • @Siriusmart maybe I am not understanding but would you mind elaborating your tic-tac-toe issue a little more? Commented Oct 12, 2021 at 17:03
  • 1
    @Siriusmart, just adding to this, from personal experience I feel rust-lang discord channel will be more helpful while new to Rust :) Commented Oct 12, 2021 at 19:32

1 Answer 1

2

In short, no, this is not possible. The names of your fields aren't necessarily available at runtime to perform such a check. However, there are other ways to achieve similar results:

  • use a HashMap<String, String>
  • write a function to do it:
impl MyStruct {
  pub fn get_field(&self, key: String) -> &str {
    if key == 'field1' {
      self.field1
    } else if ...
  }
}
  • Write a derive macro to generate the above function automatically (https://crates.io/crates/field_names might be a useful starting point for how you might go about writing a derive macro)

Or solve it a different way

This pattern is not well supported in Rust, especially compared to more dynamic languages like JavaScript. A problem many new Rust learners face is solving problems "the Rust way".

It's not 100% clear from your comment, but it sounds like your struct is representing a tic-tac-toe board and looks something like this:

struct Board {
  top_right: String,
  top_middle: String,
  top_left: String,
  // etc...
}

While this works, there are much better ways of doing this. For example, you could represent each tile with an enum instead of a String, and you could also use an Vec (similar to arrays/lists from other languages) to store that data:

enum Tile {
  Empty,
  Cross,
  Circle,
}

struct Board {
  tiles: Vec<Tile>,
}

impl Board {
  pub fn print(&self) {
    for tile in self.tiles {
      println!("{}", match tile {
        Tile::Empty => " ",        
        Tile::Cross => "X"
        Tile::Circle => "O",
      });  
    }
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Unless the size of the board is dynamic, it would probably be easier to represent it as a 2D array: tiles: [ [ Tile; 3]; 3]
100% agree. In this answer I felt like using a Vec made more sense, since it's likely a more familiar type to someone asking this sort of question, and I wanted to keep the potential "new concepts" to a minimum

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.