rust - 为什么不能将u32转换为char

来源 https://www.coder.work/article/2553893

我正在努力学习Rust,我开始思考chars是如何4字节宽的。我可以将char通过as转换 为u32并且它可以工作(它们都是4字节宽的),但是,当我将u32通过as转换为achar时,Rust抱怨道:

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}
1
2
3
4
5
error[E0604]: only `u8` can be cast as `char`, not `u32`
--> src/main.rs:12:26
|
12 | println!("{} == {}", pizza_hex as char, pizza);
| ^^^^^^^^^^^^^^^^^

你知道为什么吗?
最佳答案

每个char都是有效的u32值,但不是每个u32值都是有效的char。
包含有效Unicode码位的chars的属性:
未定义的行为
基元类型中的值无效,即使在私有字段和局部变量中也是如此:
Achar中的值,它是代理项或大于char::MAX的值。
要在运行时将au32转换为achar,请尝试以下操作:

1
2
3
if let Some(pizza_from_hex) = std::char::from_u32(pizza_hex) {
println!("{} == {}", pizza_from_hex, pizza);
}

如果您不想在字符文本中使用令人毛骨悚然的Unicode标志符号,可以使用Unicode转义序列:

1
2
3
let pizza_from_hex = '\u{01f355}';

println!("{} == {}", pizza_from_hex, pizza);

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!