Pushing a "String" to a "&mut Vec<String>" has unexpected behavior

I have the following code (that's just a snippet):

fn match_sequence(s: &mut String, unrec_seq: &mut Vec<String>, seq: char) {
  match seq {
    '\\' => s.push('\\'),
    'n' => s.push('\n'),
    _ => { unrec_seq.push(format!(r"\{}", seq)); println!("sec is: {}", seq); println!("{:?}", unrec_seq); },
  }
}

fn main() {
  match_sequence(&mut String::new(), &mut vec![String::from("Hello")], 'b');
}

The println! macro will show that seq is indeed b but when I used format to concatenate seq with \ and add the returned String to the vector, println! shows that what's inside vector is \\b. Where are there two backslashes? Just converting seq to String and adding it to the vector will just add b so I don't know if it's a bug or if I'm doing something wrong. I also tried to create a String (String::from('\')) and then push the seq and then push this String into the vector but I have the same behavior.

Are you aware of string escaping syntax? The literals "\\b" and r"\b" are the same. What’s printed is not a String containing two backslashes followed by b, but instead there only is a single backslash.

Just like \n stands for a line break or \" stands for double quote and \' for a single quote character, to write the backslash itself you’ll also need an escaping sequence, that is, \\.

fn main() {
    let s = "\" (linebreak ->) \n \' \u{AC} \\ (<- single backslash)";
    println!("{:?}", s); // print escaped and surrounded by quotes, like the
                         // literal above in the source code (except that
                         // things that don’t NEED to be escaped aren’t, i.e.
                         // the `'` in a string or the `¬` )
    println!("{}", s); // print the contents verbatim / unescaped
    
    // or for some different demonstration:
    assert_eq!(

// this string
"\" (linebreak ->) \n \' \u{AC} \\ (<- single backslash)",

// is the same as this one
r#"" (linebreak ->) 
 ' ¬ \ (<- single backslash)"#
 
    );
}

(playground)

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.96s
     Running `target/debug/playground`

----------------------- Standard Output -----------------------

"\" (linebreak ->) \n ' ¬ \\ (<- single backslash)"
" (linebreak ->) 
 ' ¬ \ (<- single backslash)

See also:

Strings - Rust By Example

Thanks, I know about that. r"\" is the same as "\\" but what does have to do with my problem. This doesn't fix my problem. Also what do you mean when saying: "What’s printed is not s String containing two backslashes followed by b, but instead there only is a single backslash."?

So are you calling my crazy? It litarely prints \\b! Have you run the code? Changing unrec_seq.push(format!(r"\{}", seq)); to unrec_seq.push(format!("\\{}", seq)); has the same output. Please run the code and write the output.

Ah, fixed the typo, missed the “a” key and hit “s” instead

Of course not,

Of course I did, and it does exactly what I’d expect it does, so I’m trying to understand what you’d expect to happen instead and why you’d expect so. My first guess was that, maybe, you’re unfamiliar with escaping syntax, and perhaps also with how debug printing of strings works. Especially because you said

1 Like

unrec_seq actually contains \b, as expected. Two backslashes appear because you're using {:?} so you get the Debug representation. Debug representation shows escaped strings so that you can copy-paste it to the code and get the same value. Display representation ({}) does not add escaping.

1 Like

I mean, I could do the same thing, I guess:

fn main() {
    println!("{:?}", "
");
}

(playground)

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.95s
     Running `target/debug/playground`
----------------------- Standard Output -----------------------
"\n"

“Where is there a backslash and the letter N?”

FUCK YEAH!!! I knew I wasn't crazy!!! Man Rust is awesome but there are some sneaky corner cases but thankfully I can get help from here and from until know, I'm very happy and grateful! Thanks a lot for everything man! Have an amazing day!

I found this issue! @Riateche explains it! Thanks a lot for your time, have an amazing day!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.