I'm trying to learn Rust and I got caught up thinking about how char
s are 4 bytes wide. I can cast a char
to a u32
and it works out (they are both 4 bytes wide), however, when I cast from a u32
to a char
, Rust complains:
fn main() {
let pizza_hex: u32 = 0x1f355;
let pizza: char = '🍕'; // (pizza char: http://www.fileformat.info/info/unicode/char/1f355/index.htm)
// pizza as hex = 1f355
println!("pizza as hex = {:x}", pizza as u32);
// size of pizza = 4
println!("size of pizza = {}", std::mem::size_of_val(&pizza));
// This doesn't work super well
println!("{} == {}", pizza_hex as char, pizza);
}
error[E0604]: only `u8` can be cast as `char`, not `u32`
--> src/main.rs:12:26
|
12 | println!("{} == {}", pizza_hex as char, pizza);
| ^^^^^^^^^^^^^^^^^
Any ideas why?
Every char
is a valid u32
value, but not every u32
value is a valid char
.
The property of char
s holding valid Unicode codepoints factors into memory safety:
Behavior considered undefined
- Invalid values in primitive types, even in private fields and locals:
- A value in a
char
which is a surrogate or abovechar::MAX
.
To convert a u32
to a char
at runtime, try this:
if let Some(pizza_from_hex) = std::char::from_u32(pizza_hex) {
println!("{} == {}", pizza_from_hex, pizza);
}
If you just don't want creepy Unicode glyphs in your character literals, you can use Unicode escape sequences:
let pizza_from_hex = '\u{01f355}';
println!("{} == {}", pizza_from_hex, pizza);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With