我本周末在Rust重新做一个项目,我需要将i32转换为ASCII字符,并将其作为字符代码。到目前为止,我所有的都是一个可怕的match
,我隐藏在文件的末尾。很遗憾,std::ascii
不支持此转换。目前我只是在寻找一种不那么荒谬/更像Rust(?)的方式来做这件事。
fn to_ascii(i: &i32) -> String {
let a = match *i {
0 => "NUL",
1 => "SOH",
2 => "STX",
// ...
125 => "}",
126 => "~",
127 => "DEL",
_ => "",
}
a
}
答案 0 :(得分:9)
首先,您无需返回String
,&'static str
就足够了。其次,您可以简单地设置一个&'static str
s数组,其中包含您喜欢的所有代码表示,并使用.get(_)
来获取相关的字符串切片,只要所有的char代码都是连续的(它们应该是如果我有我的ASCII权利)。即使它们不是,你总是可以把空字符串放在空白处。
代码应如下所示:
const CHARS: [&'static str; 128] = ["NUL", "SOH", "STX", .., "DEL"];
fn get_char_code(c: i32) -> &'static str {
CHARS.get(c as usize).unwrap_or("")
}
答案 1 :(得分:4)
对于它的价值,我不介意match
版本。唯一的调整是你不需要临时变量。我们建议您关注llogiq's answer并返回&'static str
,如果需要,您的来电者可以转换为String
:
fn get_char_code(i: &i32) -> &'static str {
match *i {
0 => "NUL",
1 => "SOH",
2 => "STX",
// ...
125 => "}",
126 => "~",
127 => "DEL",
_ => "",
}
}
此外,我高度建议不要在此代码中使用“ASCII”一词。大多数程序员将“ASCII字符”关联为单个u8
数据,这些数据映射到特定字符,标点符号或控制代码。
答案 2 :(得分:2)
您可以使用format!
宏将char
转换为String
:
fn to_ascii(i: &i32) -> String {
match *i {
x@0...127 => format!("{:?}", x as u8 as char),
_ => "".into(),
}
}
fn main() {
for x in 0x09..0x12 {
print!("{} ", to_ascii(&x));
}
println!("");
//'\t' '\n' '\u{b}' '\u{c}' '\r' '\u{e}' '\u{f}' '\u{10}' '\u{11}'
for x in 0x30..0x40 {
print!("{} ", to_ascii(&x));
}
println!("");
//'0' '1' '2' '3' '4' '5' '6' '7' '8' '9' ':' ';' '<' '=' '>' '?'
}
这会返回'\u{0}'
而不是"NUL"
,即转义码而不是缩写。如果你不喜欢它的外观,你可以使用一个巨大的匹配或字符串数组。
实际上,您只需要重新定义33个控制代码字符。对于其他可打印字符,您仍然可以使用format!
:
fn to_ascii(i: &i32) -> String {
match *i {
x@0...32 => ["NUL", "SOH", "STX", ..., "SPC"][x as usize].into(),
x@33...126 => format!("{}", x as u8 as char),
127 => "DEL".into(),
_ => "".into(),
}
}
对于更像Rust的方式,您可以使用Cow
之类的智能指针作为返回类型:
use std::borrow::Cow;
fn to_ascii(i: &i32) -> Cow<'static, str> {
match *i {
x@0...32 => ["NUL", "SOH", "STX", ..., "SPC"][x as usize].into(),
x@32...126 => format!("{}", x as u8 as char).into(),
127 => "DEL".into(),
_ => "".into(),
}
}
详细了解Cow
使用情况here。
答案 3 :(得分:0)
您可以按如下所述进行投射:
println!("{}", 'A' as i8); // prints 65
println!("{}", 65 as char); // prints 'A'
答案 4 :(得分:0)
您可以将i32
与from_u32
结合使用,而不是u32
:
use std::char::from_u32;
fn main() -> Result<(), u32> {
let n = 0x21;
let c = from_u32(n).ok_or(n)?;
println!("{}", c);
Ok(())
}