Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a char in a String? [duplicate]

Tags:

string

rust

I'm trying to update a char in a String, but can't seem to be able to do that.

fn main() {
    let mut s = "poyo".to_string();
    // s[1] = 'i'; or s.get_mut(1) = 'i'; can't do either
    println!("{}", s); // expecting "piyo"
}

I know why this happens (String does not implement IndexMut<usize>), but I don't know how to resolve this...

playground link

like image 484
yumizu rai Avatar asked Oct 18 '25 11:10

yumizu rai


1 Answers

The answer depends on the sort of String you are dealing with; if you are working with ASCII only (which means every character is one byte in size and you can just directly manipulate the underlying Vec<u8>), you could do the following:

fn main() {
    let mut s = "poyo".to_string();
    let mut bytes = s.into_bytes();
    bytes[1] = 'i' as u8;

    unsafe { s = String::from_utf8_unchecked(bytes) }

    println!("{}", s);
}

or:

fn main() {
    let mut s = "poyo".to_string();

    unsafe {
        let bytes = s.as_bytes_mut();
        bytes[1] = 'i' as u8;
    }

    println!("{}", s);
}

If, however, you are (potentially) working with multi-byte characters (which is the whole reason why String doesn't implement IndexMut or even Index), the safe way to do it would be to use the Chars iterator, walk over it and create a new String based on its elements:

fn main() {
    let s = "poyo".to_string();
    let iter = s.chars();
    let mut new = String::new();

    for (i, mut c) in iter.enumerate() {
        if i == 1 { c = 'i'; }
        new.push(c);
    }

    println!("{}", new);
}
like image 173
ljedrz Avatar answered Oct 21 '25 02:10

ljedrz