除递归外,有无更优的无限输入校验方式?(Rust井字棋场景)
Rust风格的自定义棋盘尺寸输入优化方案
当前实现用递归处理无效输入,虽能避免程序崩溃,但存在逻辑分散、代码不够简洁的问题,以下是更符合Rust惯用风格的优化方案:
优化思路
- 用迭代循环替代递归:避免递归栈溢出风险(实际输入次数有限,但迭代逻辑更直观)
- 集中验证逻辑:将输入读取、格式解析、范围校验整合到单一函数,职责更清晰
- 利用Result类型做错误处理:明确区分解析成功与失败状态,契合Rust错误处理习惯
优化后的代码示例
use std::io::{self, Write}; fn main() { let (width, height) = get_valid_board_size(); println!("你选择的棋盘尺寸是:{}x{}", width, height); // 后续游戏逻辑... } fn get_valid_board_size() -> (i64, i64) { loop { // 打印提示信息 println!("请选择棋盘尺寸,格式为:5x5 或 7x7"); println!("尺寸范围:3x3 到 30x30"); print!("输入尺寸:"); io::stdout().flush().expect("刷新标准输出失败"); // 读取输入 let mut input = String::new(); io::stdin().read_line(&mut input).expect("读取输入失败"); let input = input.trim(); // 解析输入格式 let parts: Vec<&str> = input.split('x').collect(); if parts.len() != 2 { println!("错误:输入必须包含一个'x'分隔符!\n"); continue; } // 解析宽度和高度 let (width_str, height_str) = (parts[0], parts[1]); let (width, height) = match (width_str.parse::<i64>(), height_str.parse::<i64>()) { (Ok(w), Ok(h)) => (w, h), _ => { println!("错误:宽度和高度必须是有效数字!\n"); continue; } }; // 验证尺寸范围 if (3..=30).contains(&width) && (3..=30).contains(&height) { return (width, height); } else { println!("错误:尺寸必须在3到30之间!\n"); } } }
优化点说明
- 循环驱动的重试逻辑:通过
loop循环持续获取输入,直到得到有效数据,比递归更直观,也避免了递归栈的潜在问题 - 单一职责函数:
get_valid_board_size整合了所有输入相关逻辑,从提示、读取到解析、校验,代码更紧凑易读 - 明确的错误反馈:针对不同错误场景(格式错误、数字无效、范围超限)给出精准提示,提升用户体验
- 避免冗余调用:原递归实现中每次错误都要重复调用多个函数,优化后一次循环完成所有校验,减少不必要的函数调用
内容的提问来源于stack exchange,提问作者NaniNoni
相关产品推荐
相关产品推荐

