I recently started learning rust, and I was ready for one hell of a fight. I heard all those horror Storys about the compiler complaining about every single detail and that developing rust means having a constant fight with the compiler about seemingly irrelevant things. However, so far I have to tell, that while its somewhat true, that the compiler is somewhat picky, it is incredibly helpful. Never before have I seen such good and helpful compiler messages. It not only says what you did wrong, but also gives direct help on what to do to fix your code. I also really like, that it gives you direct references to the rust book in the compiler messages.

Prior to starting my journey with rust I did quite a lot of python, some C and some bash and their interpreter/compiler messages are nothing when comparing them with rust. Especially the bash error messages are awful if you do not know what they mean and how to fix them.

  • da_cow (she/her)@feddit.orgOP
    link
    fedilink
    arrow-up
    0
    ·
    12 days ago

    Currently I am trying to figure out how to access and change single characters in a string (I am coding a basic version of hangman to get used to working with rust). The main problem I have is, that I can not figure out how to change the value of a single character in a string based on its index. I have a string (that has the same length as my “word to guess”) containing only underscores and whenever the user correctly guesses a character I want to replace the underscores by the guessed character to show the user how much he has guessed so far. I was able to turn the string into a char iterator, but I could not figure out how to change elements of said iterator (this can be seen at line 55).

    The code is here: https://pastebin.com/kfSYWT42`___`

    • Miaou@jlai.lu
      link
      fedilink
      arrow-up
      0
      ·
      12 days ago

      This is simply not possible in rust, because strings are utf-8, so the size of a single character can vary. I think there might be a class for ASCII strings, but otherwise you can just use Vev<U8> and then convert to string

    • TehPers@beehaw.org
      link
      fedilink
      English
      arrow-up
      0
      ·
      12 days ago

      I was able to turn the string into a char iterator, but I could not figure out how to change elements of said iterator (this can be seen at line 55).

      You have a few options here, but the easiest is to collect into a Vec<char>, replace the character there, then do a String::from_iter(chars) to get it back as a string.

      You can also manipulate the original chars iterator directly through takes, skips, and so on and collect it into a string, but that’s more complicated.

      Also, “character” is such a complicated concept because unicode is not simple. If you can work directly with bytes though, you can convert the string to a Vec<u8> (which is the underlying type for String), manipulate that directly, then do String::from_utf8 (or the same method for str) to convert it back to a string.

      • semi [he/him]@lemmy.ml
        link
        fedilink
        arrow-up
        0
        ·
        12 days ago

        Since OP will want to do a lot of character based operations for the hangman game, she could also consider using Vec<char> as an internal representation everywhere and only converting into String for display purposes.

        • TehPers@beehaw.org
          link
          fedilink
          English
          arrow-up
          0
          ·
          12 days ago

          I agree, this makes the most sense. I was under the assumption they wanted to keep it as a String, but your suggestion is a better way to approach the problem if they’re able to do that.

    • SorteKanin@feddit.dk
      link
      fedilink
      arrow-up
      0
      ·
      12 days ago

      Others have already pointed out the issue - in Rust, String is UTF-8 encoded and therefore characters are variable length. So you can’t just change a character in a string, as it may not fit (e.g. replacing ‘a’ with ‘🙂’ would lead to trouble).

      You can do what the others suggest, but honestly for a game like hangman, I’d suggest you just work directly with chars and don’t use any string. As in, just use a Vec<char> instead of a string. Then you can freely change characters based on index, but this representation uses more memory than a typical String. But this won’t matter for your use case.

      • da_cow (she/her)@feddit.orgOP
        link
        fedilink
        arrow-up
        0
        ·
        12 days ago

        Working with a vector directly would probably be easier, however for a learning experience this was actually great. I read through quite a lot of documentation trying to figure out how I achieve what I want. Might reimplement it with vectors later just for the learning experience.

    • Glyn Wolf :verified_gay:@tiggi.es
      link
      fedilink
      arrow-up
      0
      ·
      12 days ago

      @cows_are_underrated The simplest way I’ve found to do that is to convert the string into a Vec<char>. UTF-8 strings aren’t optimized for random access because of multi-byte chars.

      To array of chars:
      let c = s.chars().collect::<Vec<char>>();

      And back to string:
      let s = c.into_iter().collect::<String>();