Rust中对char调用.to_digit()后unwrap报错,两种用法差异是什么?
问题解答
代码报错与示例运行正常的原因
char类型的to_digit(radix)方法的功能是将表示指定进制数字的字符转换为对应的整数值,入参radix为进制数,传入10时仅能转换'0'~'9'范围的十进制数字字符,其他字符调用该方法会返回None。
- 你的代码存在两个问题:
- 变量名不匹配:你定义的字符变量是
char_variable,但调用方法时写的是a.to_digit(10),会先触发变量未定义的语法错误。 - 字符不是合法十进制数字:就算你修正变量名,你用的字符是
'a',不属于'0'~'9'范围,to_digit(10)返回None,调用unwrap()就会触发解包空值的panic,也就是你遇到的报错。
- 变量名不匹配:你定义的字符变量是
- 示例代码中的字符串是
"29",遍历得到的字符是'2'和'9',都是合法的十进制数字字符,to_digit(10)会返回包含对应数值的Some值,不会触发panic。
强制转换写法的可行性分析
你写的c as u32 - 48的逻辑是利用ASCII编码中'0'对应数值48的特性做转换,这种写法仅在你能100%保证字符是ASCII编码的'0'~'9'数字字符时能得到正确结果,但存在明显缺陷:
- 没有校验机制:如果字符不是数字,会得到无意义的错误值,且不会有任何报错,很难排查问题。
- 不支持非ASCII数字:Rust的
char是Unicode标量值,如果你遇到全角数字(比如'1')等非ASCII数字字符,该写法会返回错误结果,而to_digit方法原生支持这类数字字符的转换。
推荐实现方案
根据你的需求选择对应方案:
- 如果你需要将数字字符转换为对应十进制数值,优先使用
to_digit(10),同时做好空值处理,避免直接调用unwrap():
let c = '3'; match c.to_digit(10) { Some(num) => { // 拿到正确的数值3,执行后续逻辑 println!("转换结果:{}", num); }, None => { // 处理字符不是数字的异常场景 println!("输入字符不是合法十进制数字"); } }
如果你的业务逻辑能100%保证输入字符是数字,可以使用unwrap(),建议添加注释说明前提。
2. 如果你需要获取十六进制字符(af/AF)对应的数值,将to_digit的入参改为16即可:
let c = 'a'; let num = c.to_digit(16).unwrap(); // 得到十六进制a对应的数值10
- 如果你只是需要获取字符的Unicode编码值,不需要转数字含义,直接使用
as u32即可,不需要减48:
let c = 'a'; let unicode_code = c as u32; // 得到'a'的Unicode编码值97
内容的提问来源于stack exchange,提问作者Krzysztof Kaczyński
相关产品推荐
相关产品推荐

