3 个稳定版本
1.1.1 | 2023年7月14日 |
---|---|
1.1.0 | 2023年7月9日 |
1.0.0 | 2023年1月18日 |
在 国际化 (i18n) 中排名 30
每月下载量 2,114
在 19 个 Crates 中使用(直接使用 4 个)
68KB
1K SLoC
快速且友好的 Rust 数字格式化。
格式化数字。
提供用于使用各种方法格式化十进制数字的 Formatter
。格式化注重性能,通常比 std
更快,功能更丰富。还有一个可以按照特定语法使用字符串来定义 Formatter
的 字符串解析器。
过程
格式化通过遵循以下程序的 Formatter::fmt
来完成:
用法
默认用法
Default::default
提供一个具有以下属性的通用默认格式化器
Scales::short
缩放,,
千位分隔符,- 3 位小数
# use numfmt::*;
let mut f = Formatter::default();
assert_eq!(f.fmt(0.0), "0");
assert_eq!(f.fmt(12345.6789), "12.345 K");
assert_eq!(f.fmt(0.00012345), "1.234e-4");
assert_eq!(f.fmt(123456e22), "1,234.559 Y");
自定义用法
Formatter
提供许多不同的选项来自定义数字的格式化方式。以下示例显示了如何开发货币格式
# use numfmt::*;
let mut f = Formatter::new() // start with blank representation
.separator(',').unwrap()
.prefix("AU$").unwrap()
.precision(Precision::Decimals(2));
assert_eq!(f.fmt(0.52), "AU$0.52");
assert_eq!(f.fmt(1234.567), "AU$1,234.56");
assert_eq!(f.fmt(12345678900.0), "AU$12,345,678,900.0");
科学记数法
当缩放后的数字大于 12 位整数数字(123,456,789,000)或小于 3 位前导零(0.0001234)时,将启动科学记数法。数字 始终 有一个前导整数数字,默认为 7 位有效数字。
精度
可以通过Precision
指定精度,无论是小数位数还是有效数字。
# use numfmt::*;
let mut f = Formatter::new();
assert_eq!(f.fmt(1234.56789), "1234.56789");
f = f.precision(Precision::Decimals(2));
assert_eq!(f.fmt(1234.56789), "1234.56");
f = f.precision(Precision::Significance(5));
assert_eq!(f.fmt(1234.56789), "1234.5");
性能
格式化通常比std
的f64::to_string
实现要快。当构造一个Formatter
时,会有一个缓冲区的分配,以及任何缩放的分配。建议重用Formatter
以避免不必要的分配。在cached
行中显示了重用格式化器后的更好性能。
时间(纳秒) | 0.0 | 0.1234 | 2.718281828459045 | 1.797693148623157e307 |
---|---|---|---|---|
numfmt - 默认 | 35 | 115 | 153 | 195 |
numfmt - 缓存 | 2 | 75 | 89 | 126 |
std | 35 | 96 | 105 | 214 |
示例 - 文件大小格式化器
通过组合缩放、后缀和精度,可以构建一个文件大小打印机。
# use numfmt::*;
let mut f = Formatter::new()
.scales(Scales::binary())
.precision(Precision::Significance(3))
.suffix("B").unwrap();
assert_eq!(f.fmt(123_f64), "123 B");
assert_eq!(f.fmt(1234_f64), "1.20 kiB");
assert_eq!(f.fmt(1_048_576_f64), "1.0 MiB");
assert_eq!(f.fmt(123456789876543_f64), "112 TiB");
解析
定义了一个语法,可以将数据解析为Formatter
。这种字符串表示可以用于格式化数字的用户输入。语法由一个前缀、括号内的数字格式和一个后缀定义。
prefix[[.#|~#|.*][%|s|b|n][/<char>]]suffix
^----^ ^--------^^-------^^-------^ ^----^
prefix precision scale separator suffix
每个组件都是可选的,包括数字格式。所有格式都应用于默认
Formatter
,因此空格式将导致默认的格式化器。
前缀和后缀
前缀和后缀绑定到支持的长度,并且可以包含任何字符。要使用[]
字符,必须使用双括号。
示例
# use numfmt::*;
let mut f: Formatter;
f = "".parse().unwrap();
assert_eq!(f.fmt(1.234), "1.234");
f = "prefix ".parse().unwrap();
assert_eq!(f.fmt(1.234), "prefix 1.234");
f = "[] suffix".parse().unwrap();
assert_eq!(f.fmt(1.234), "1.234 suffix");
f = "[[prefix [] suffix]]".parse().unwrap();
assert_eq!(f.fmt(1.234), "[prefix 1.234 suffix]");
精度
使用点.
定义小数精度,或使用~
定义有效数字精度,后跟一个数字。支持的最多为255。有一个特殊情况:.*
移除任何默认精度并使用Precision::Unspecified
。
示例
# use numfmt::*;
let mut f: Formatter;
f = "[.2]".parse().unwrap(); // use two decimal places
assert_eq!(f.fmt(1.2345), "1.23");
f = "[.0]".parse().unwrap(); // use zero decimal places
assert_eq!(f.fmt(10.234), "10");
f = "[.*]".parse().unwrap(); // arbitary precision
assert_eq!(f.fmt(1.234), "1.234");
assert_eq!(f.fmt(12.2), "12.2");
f = "[~3]".parse().unwrap(); // 3 significant figures
assert_eq!(f.fmt(1.234), "1.23");
assert_eq!(f.fmt(10.234), "10.2");
缩放
缩放使用一个字符来表示应该使用哪种缩放。默认情况下使用SI缩放。以下字符被支持
s
代表SI缩放(Scales::short
),%
代表百分比缩放(Formatter::percentage
),m
代表公制缩放(Scales::metric
),b
代表二进制缩放(Scales::binary
),n
代表无缩放(Scales::none
)
示例
# use numfmt::*;
let mut f: Formatter;
f = "".parse().unwrap(); // default si scaling used
assert_eq!(f.fmt(12345.0), "12.345 K");
f = "[n]".parse().unwrap(); // turn off scaling
assert_eq!(f.fmt(12345.0), "12,345.0");
f = "[%.2]".parse().unwrap(); // format as percentages with 2 decimal places
assert_eq!(f.fmt(0.234), "23.40%");
f = "[b]".parse().unwrap(); // use a binary scaler
assert_eq!(f.fmt(3.14 * 1024.0 * 1024.0), "3.14 Mi");
分隔符
可以通过使用一个跟随字符的斜杠/
来指定一个分隔符字符。解析器使用下一个字符字面量,除非该字符是]
,在这种情况下,分隔符被设置为None
。默认分隔符是逗号。
示例
# use numfmt::*;
let mut f: Formatter;
f = "[n]".parse().unwrap(); // turn off scaling to see separator
assert_eq!(f.fmt(12345.0), "12,345.0");
f = "[n/]".parse().unwrap(); // use no separator
assert_eq!(f.fmt(12345.0), "12345.0");
f = "[n/.]".parse().unwrap(); // use a period
assert_eq!(f.fmt(12345.0), "12.345.0");
f = "[n/_]".parse().unwrap(); // use a underscroll
assert_eq!(f.fmt(12345.0), "12_345.0");
f = "[n/ ]".parse().unwrap(); // use a space
assert_eq!(f.fmt(12345.0), "12 345.0");
组合格式
已经有一些关于格式组合的例子了。必须遵守 prefix[num]suffix
的顺序,但数字格式内的排序是任意的。建议保持与 精度、缩放、分隔符 的一致性,这有助于提高可读性并降低格式错误(在解析阶段将产生错误)的风险。
各种组合示例
# use numfmt::*;
let mut f: Formatter;
// Percentages to two decimal places
f = "[.2%]".parse().unwrap();
assert_eq!(f.fmt(0.012345), "1.23%");
// Currency to zero decimal places
// notice the `n` for no scaling
f = "$[.0n] USD".parse().unwrap();
assert_eq!(f.fmt(123_456_789.12345), "$123,456,789 USD");
// Formatting file sizes
f = "[~3b]B".parse().unwrap();
assert_eq!(f.fmt(123_456_789.0), "117 MiB");
// Units to 1 decimal place
f = "[.1n] m/s".parse().unwrap();
assert_eq!(f.fmt(12345.68), "12,345.6 m/s");
依赖项
~52KB