use std::fmt::Display;
fn commafy<T: Display>(num: T) -> String {
let num = format!("{:.2}", num);
let (signal, num) = num.split_at(num.find("-").map(|x| x + 1).unwrap_or(0));
let (int, fraction) = num.split_at(num.find(".").unwrap_or(num.len()));
let len = int.len();
let c3 = |x| if len >= x * 3 { len - x * 3 } else { 0 };
let int = (0..len / 3 + 1)
.map(|i| int.get(c3(i + 1)..c3(i)).unwrap())
.rev()
.filter(|x| x.len() > 0)
.fold("".to_string(), |result, part| {
let sep = if result.is_empty() { "" } else { "," };
result + sep + part
});
signal.to_string() + &int + &fraction
}
fn main() {
let n = 12345678901223i64;
println!("{}", commafy(n));
let n = -12345678901223i64;
println!("{}", commafy(n));
let n = 12345678901223.128;
println!("{}", commafy(n));
let n = -123456789012239.19;
println!("{}", commafy(n));
}
nothing ⇒ Display
? ⇒ Debug
x? ⇒ Debug with lower-case hexadecimal integers
X? ⇒ Debug with upper-case hexadecimal integers
o ⇒ Octal
x ⇒ LowerHex
X ⇒ UpperHex
p ⇒ Pointer
b ⇒ Binary
e ⇒ LowerExp
E ⇒ UpperExp
c ⇒ CommaSep
use comma_sep:CommaSep;
fn main() {
let num=1234567.343f64;
assert_eq!("1,234,567.34",format!("{:12.2c}",num));
}
评论区
写评论看来是把简单问题搞复杂了,其实写一个简单函数就解决问题了:
程序运行结果:
各位大咖,还有更精简的写法吗?
我的意思是:引入一种新的显示类型,比如c,对应一个trait, 比如CommaSep
可以,加一个trait就行
打印
给你想要格式化的所有类型都实现这个trait即可,这里就实现一个i64和f64,觉得重复代码多可以用宏来搞。不知道是否符合你的要求。
这样吗