You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用简单循环打印Rust中的所有char字符?

问题分析

你的代码触发panic有两个核心问题:

  1. 范围定义错误:第一个范围的上限写成了0xffD7FF,这是笔误,正确上限应为0xD7FF。0xffD7FF远超出合法char的范围,导致循环会进入UTF-16代理区(U+D800至U+DFFF),而这部分值无法转换为Rust的char类型。
  2. 循环逻辑错误:你在循环里先执行i += 1再判断范围,既跳过了每个范围的起始字符(比如U+0000),又会在i走到U+D800时,因该值属于无效代理区,导致char::from_u32(i)返回None,触发expect的panic。
修正方案

方案一:修复原代码逻辑

修正范围定义,调整循环顺序,同时做安全转换避免panic:

use std::io::{self, Write};

fn main() {
    // 修正合法范围的边界值
    let ranges = [(0x0000, 0xD7FF), (0xE000, 0x10FFFF)];
    for (start, end) in ranges {
        let mut i = start;
        loop {
            // 先尝试转换为char,成功再打印
            if let Some(c) = char::from_u32(i) {
                print!("{}", c);
                let _ = io::stdout().flush();
            }
            // 到达范围末尾时终止循环
            if i == end {
                break;
            }
            i += 1;
        }
    }
}

方案二:更简洁的Rust风格实现

Rust的char类型原生支持合法范围的迭代,会自动跳过无效代理区,代码更简洁安全:

use std::io::{self, Write};

fn main() {
    // 合并两个合法char范围的迭代器,直接遍历所有有效字符
    for c in ('\u{0000}'..='\u{D7FF}').chain('\u{E000}'..='\u{10FFFF}') {
        print!("{}", c);
        let _ = io::stdout().flush();
    }
}
关键说明
  • Rust的char严格对应Unicode标量值,禁止U+D800至U+DFFF的代理对代码点,这是触发panic的直接原因。
  • 使用char的范围迭代器(..=)会自动过滤无效值,无需手动处理边界,是推荐写法。
  • 调用stdout().flush()是必要的,因为print!默认是行缓冲,不手动刷新无法实时输出字符到控制台。

内容的提问来源于stack exchange,提问作者OV3RKILL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:12