Вы задаете вопрос:
Как поместиться 32-разрядное число в 8-битное значение?
Который имеет немедленный ответ: «выбросить большую часть битов»:
let c = rust_character as libc::c_char;
Однако, это должно заставить вас остановиться и задать вопросы:
- Перечислим остальные бит в правильной кодировке?
- Как насчет всех этих бит, которые я выбросил?
Rust char
s разрешает кодирование всех сканирующих значений Unicode. Что такое вашего желаемого поведения для этого кода:
let c = '' as libc::c_char;
Это, вероятно, не создавать значение -87
, значение не-ASCII! Или это менее глупо и, возможно, более реалистичный вариант, который -17
:
let c = 'ï' as libc::c_char;
Вы тогда должны спросить: что делает код C означает, по характеру? Какова кодировка строк кода C? Как код C обрабатывает текст без ASCII?
Самое безопасное может утверждать, что значение находится в пределах диапазона ASCII:
let c = 'ï';
let v = c as u32;
assert!(v <= 127, "Invalid C character value");
let v = v as libc::c_char;
Вместо того, чтобы утверждать, вы можете также вернуть Result
тип, который указывает, что значение было вне диапазона.
Я должен изменить свою функцию (тот, который будет вызывать функцию клея), чтобы получить c_char
вместо char
?
Это зависит. Это может просто подтолкнуть проблему вверх по стеку; теперь каждый вызывающий должен решить, как создать c_char
и беспокоиться о значениях между 128 и 255. Если семантика вашего кода такова, что значение должно быть символом ASCII, то кодирует это в ваших типах. В частности, вы можете использовать что-то вроде ascii crate.
В любом случае вы нажимаете на возможность отказа от чужого кода, что облегчает вашу жизнь с потенциальным расходом, чтобы сделать вызывающего абонента более расстроенным.
Сделать утверждение будет правильным способом его обработки или изменить мою функцию (ту, которая вызовет функцию клея), чтобы получить 'c_char' вместо' char'? – Sassa
Большое спасибо за подробный и очень проницательный ответ! – Sassa