Вы не можете изменить срез строки вообще. &mut &str
не является подходящим типом в любом случае, потому что он буквально является изменяемым указателем на неизменяемым фрагментом. И все строка ломтики неизменяемы.
В строках Rust действительны последовательности UTF-8, а UTF-8 - кодирование с переменной шириной. Следовательно, в общем случае изменение символа может изменить длину строки в байтах. Это невозможно сделать с помощью срезов (поскольку они всегда имеют фиксированную длину), и это может привести к перераспределению для принадлежащих строк. Более того, в 99% случаев изменение символа внутри строки не то, что вы действительно хотите.
Для того, чтобы сделать то, что вы хотите с Юникодом кодовых вам нужно сделать что-то вроде этого:
fn replace_char_at(s: &str, idx: uint, c: char) -> String {
let mut r = String::with_capacity(s.len());
for (i, d) in s.char_indices() {
r.push(if i == idx { c } else { d });
}
r
}
Однако это O(n)
эффективности, поскольку он должен перебирать оригинальный кусочек, и он также выиграл «Правильно работать со сложными символами - это может заменить письмо, но оставить акцент или наоборот.
Более правильный способ для обработки текста является перебирать графема кластеры, он будет принимать диакритических и другие подобные вещи правильно (в основном):
fn replace_grapheme_at(s: &str, idx: uint, c: &str) -> String {
let mut r = String::with_capacity(s.len());
for (i, g) in s.grapheme_indices(true) {
r.push_str(if i == idx { c } else { g });
}
r
}
Существует также некоторая поддержка для чистых ASCII строк в std::ascii
модуле, но, скорее всего, он скоро будет реформирован. Во всяком случае, это, как он может быть использован:
fn replace_ascii_char_at(s: String, idx: uint, c: char) -> String {
let mut ascii_s = s.into_ascii();
ascii_s[idx] = c.to_ascii();
String::from_utf8(ascii_s.into_bytes()).unwrap()
}
Это будет паниковать, если либо s
содержит не-ASCII символы или c
не является ASCII-символов.
Что заставляет вас думать, что '& str' или' String' реализуют 'IndexMut'? Unicode гораздо более сложнее, чем это, и, следовательно, чтобы избежать ошибок, они этого не делают. Я не уверен, как достичь того, что вы хотите сделать, хотя ... –
Возможно, мой фон C, который заставляет меня хотеть индексировать строки. Я понимаю, что это невозможно в ржавчине? Нужно ли использовать цикл? Предположим, я просто хочу отредактировать 100-й символ в строке, которую мне нужно будет перебрать через первые 99, прежде чем я смогу отредактировать 100-й? – Semi