【问题标题】:Why can't I cast a `u32` to `char`?为什么我不能将 `u32` 转换为 `char`?
【发布时间】:2014-09-29 20:00:56
【问题描述】:

我正在尝试学习 Rust,但我开始思考 chars 是 4 字节宽的。我可以将 char 转换为 u32 并且可以解决(它们都是 4 字节宽),但是,当我从 u32 转换为 char 时,Rust 抱怨:

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);
   |                          ^^^^^^^^^^^^^^^^^

有什么想法吗?

【问题讨论】:

标签: rust


【解决方案1】:

每个char 都是一个有效的u32 值,但不是每个u32 值都是一个有效的char

chars 的属性持有有效的 Unicode 代码点factors into memory safety

被视为未定义的行为

  • 原始类型中的无效值,即使在私有字段和局部变量中:
    • char 中的一个值,它是char::MAX 的替代值或更高版本。

要在运行时将 u32 转换为 char,请尝试以下操作:

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

如果您只是不想在字符文字中出现令人毛骨悚然的 Unicode 字形,您可以使用 Unicode 转义序列:

let pizza_from_hex = '\u{01f355}';

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

【讨论】:

  • 所以在我有一个有效的 unicode 字符 (0x1f355) 作为u32 的情况下,我仍然无法转换它吗? (高度人为的示例警告:)如果我想打印出一个不可见的字符(例如零宽度空间),我将不得不在 unsafe 块中处理字符串处理的内部?
  • 对不起,刚刚修改了我的答案。这里不需要unsafe,stdlib 包装了unsafe 逻辑。
  • 我认为在必须打印某些已知字符的情况下,转义序列/文档可能最适合奇怪的字形。
  • 我觉得std::mem::transmute也可以用在这种情况下?并且想知道是否有一种方法可以在不涉及 stdlib 的情况下进行转换。
  • 有没有办法用最接近的有效值“unwrap_or”?
猜你喜欢
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 2013-03-20
  • 2011-11-20
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
相关资源
最近更新 更多