Modifying a String (or &str) by indexing
⚓ Rust 📅 2025-09-12 👤 surdeus 👁️ 9As part of learning Rust, I chose to convert a word scrambling code from a C++ example. The C++ is pretty straightforward and in fact could just as well be C with a null-terminated string and using strlen (although in modern C++ the last three statements would probably be done with std::swap():
string jumble = word;
int len = jumble.size();
for (int i = 0; i < len; ++i) {
int idx1 = (rand() % len);
int idx2 = (rand() % len);
char tmp = jumble[idx1];
jumble[idx1] = jumble[idx2];
jumble[idx2] = tmp;
}
At first I banged my head against the compiler because word and jumble where &str and it kept telling me I couldn't index into it, or something didn't have a size or, of course, I couldn't borrow immutably twice. My implementation stands as follows:
let mut jumble = String::from(word);
let len = jumble.len();
for _ in 0..len {
let idx1 = rng.random_range(0..len) as usize;
let idx2 = rng.random_range(0..len) as usize;
let tmp = &jumble.clone()[idx1..idx1 + 1];
jumble.replace_range(idx1..idx1 + 1, &jumble.clone()[idx2..idx2 + 1]);
jumble.replace_range(idx2..idx2 + 1, tmp);
}
I understand that indexing into UTF-8 strings is not advisable, even if one knows the strings are all plain ASCII. However, the "solution" appears to be doing a lot of unnecessary work compared to the C/C++ version (I haven't looked at the generated code). OTOH, a fully UTF-8 compliant solution would probably have to convert jumble to Rust chars to swap same-sized items with ease (I hope) and then revert the result to a String.
Anyway, if there's a more idiomatic way to do the above (other than the Unicode conversion), please let me know.
5 posts - 4 participants
🏷️ Rust_feed