Как преобразовать u8 в символ в Rust?

У меня есть функция, которая создает строку на основе значений u8 в массиве. Если u8 равен 0 или 10, я нажимаю определенный символ. В противном случае я хочу нажать на сам номер. Моя проблема в том, что когда я печатаю результат этой функции, я получаю экранированные числа. Вот код:

fn convert_result_to_string(guess_result: &[u8; SEQ_LEN]) -> String {
    let mut output = String::new();

    for (i, num) in guess_result.iter().enumerate() {

        if *num == 0 {
            output.push_str("*");
        }
        else if *num == 10 {
            output.push_str("$");
        }
        else {
            output.push(*num as char);
        }
        if i < SEQ_LEN-1 {
            output.push(' ');
        }
    }

    output
}

Позже, когда я позвоню в

let test = [0, 5, 6, 10, 7];
let o = convert_result_to_string(&test);
println!("o: {:?}", o);

Я получаю следующий результат:

o: "* \u{5} \u{6} $ \u{7}"

Почему 5, 6 и 7 сбежали?

Я не знаю Rust, но учтите, что символ 5 (Ctrl-E) — это не то же самое, что '5' (цифра 5, код ASCII/Unicode 53).

Keith Thompson 23.04.2024 04:05
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
2
1
974
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете просто преобразовать u8 в char и ожидать, что результат отобразит цифру. Цифры 0–9 представлены кодовыми точками ASCII (и Unicode) 48–57. Кодовые точки ASCII 0–9 состоят из нулевого символа, пробелов и управляющих символов, которые больше не используются широко.

Эти символы экранируются, поскольку вы используете форматирование отладки ({:?}) для отображения строки, а кодовые точки ASCII 5, 6 и 7 обычно отображаются как поля-заполнители или невидимы, в зависимости от используемого шрифта или эмулятора терминала. Таким образом, при форматировании с использованием отладочного форматирования Rust показывает вам, что вам нужно будет вставить в исходный код Rust, чтобы получить эквивалентную строку в удобочитаемой форме, которая не зависит от того, как шрифт или эмулятор терминала представляют эти символы. При этом используется escape-последовательность Юникода \u Rust для встраивания этих непоследовательно отображаемых символов в строку.

В вашем случае вы, вероятно, ищете char::from_digit().

output.push(char::from_digit((*num).into(), 10).expect("digit must be in the range 0-9"));

(Детская площадка)


Обратите внимание, что приведенный выше код вызовет панику, если значение *num не находится в диапазоне от 0 до 9 (включительно). Подумайте о том, чтобы сделать что-то вроде этого, что также будет обрабатывать многозначные десятичные числа:

write!(output, "{num}").unwrap();

Он также намного короче и не может подвести. (реализация Stringstd::fmt::Write безошибочна.)

Обратите внимание, что для этого вам потребуется use std::fmt::Write; в вашем модуле/функции.

(Детская площадка)

Другие вопросы по теме