Rust文本格式化库rt-format的使用:高效灵活的字符串与数据格式化工具

Rust文本格式化库rt-format的使用:高效灵活的字符串与数据格式化工具

rt-formatformat!宏的完全运行时等价实现。它允许像format!宏一样格式化字符串,但格式化字符串和参数是在运行时提供的。这个crate支持format!宏的所有格式化功能,除了填充字符。

何时(不)使用这个crate

有许多crate可用于将值格式化为字符串。以下是您可以用来决定这个crate是否适合您的一些标准:

  • 您可以在编译时指定所有格式化选项吗?如果是,那么std::fmt是比这个crate更好的选择。如果您需要在运行时提供格式化说明符,那么这个crate可能是一个可行的选择。
  • 您只格式化数字吗?如果是,考虑num-runtime-fmtnum-format
  • 使用Rust nightly版本是一个选项吗?如果是,考虑runtime-fmt
  • 您需要实现新格式的能力吗?如果是,考虑dynfmt
  • 您需要no-std支持吗?如果是,您需要使用其他替代方案之一。
  • 格式化很可能是您的性能瓶颈吗?如果是,您应该考虑其他替代方案。目前,没有基准测试来比较这个crate中的方法与其它crate的方法。
  • 稳定的API是必须的吗?如果是,您可能会考虑替代方案。这个crate还没有达到1.0版本,这意味着API仍然不完全稳定。

安装

在您的项目目录中运行以下Cargo命令:

cargo add rt-format

或者将以下行添加到您的Cargo.toml中:

rt-format = "0.3.1"

示例代码

use rt_format::format;

fn main() {
    // 基本格式化
    let formatted = format!("Hello, {}!", "world");
    println!("{}", formatted);
    
    // 数字格式化
    let num = 42;
    let formatted_num = format!("The answer is: {:03}", num);
    println!("{}", formatted_num);
    
    // 复杂格式化
    let name = "Alice";
    let age = 30;
    let formatted_complex = format!("{name} is {age} years old and {height:.2} meters tall", 
        name = name,
        age = age,
        height = 1.75
    );
    println!("{}", formatted_complex);
    
    // 运行时指定的格式化字符串
    let format_string = "Today is {month} {day}, {year}";
    let formatted_runtime = format(format_string, 
        month = "January",
        day = 1,
        year = 2023
    );
    println!("{}", formatted_runtime);
}

完整示例demo

use rt_format::{format, ParsedFormat, FormatArgument};

fn main() {
    // 1. 基本格式化示例
    basic_formatting();
    
    // 2. 数字格式化示例
    number_formatting();
    
    // 3. 复杂格式化示例
    named_arguments_formatting();
    
    // 4. 运行时动态格式化字符串
    dynamic_format_string();
    
    // 5. 高级用法:预解析格式字符串
    pre_parsed_format();
}

// 基本格式化
fn basic_formatting() {
    let formatted = format!("Hello, {}!", "world");
    println!("基本格式化: {}", formatted);
}

// 数字格式化
fn number_formatting() {
    let num = 3.1415926;
    let formatted = format!("圆周率: {:.2}", num);
    println!("数字格式化: {}", formatted);
}

// 命名参数格式化
fn named_arguments_formatting() {
    let formatted = format!(
        "{product}价格: {price:.2}元,库存: {stock}件",
        product = "Rust编程书",
        price = 99.99,
        stock = 100
    );
    println!("命名参数格式化: {}", formatted);
}

// 运行时动态格式化字符串
fn dynamic_format_string() {
    let template = "用户{name}的{item}消费了{amount:.2}元";
    let name = "张三";
    let item = "午餐";
    let amount = 28.50;
    
    let formatted = format(template, name = name, item = item, amount = amount);
    println!("动态格式化: {}", formatted);
}

// 预解析格式字符串提高性能
fn pre_parsed_format() {
    let template = "日期: {year}-{month:02}-{day:02}";
    let parsed = ParsedFormat::parse(template).unwrap();
    
    let year = 2023;
    let month = 8;
    let day = 15;
    
    let formatted = parsed.format(&[
        ("year", FormatArgument::from(&year)),
        ("month", FormatArgument::from(&month)),
        ("day", FormatArgument::from(&day)),
    ]).unwrap();
    
    println!("预解析格式化: {}", formatted);
}

这个完整示例展示了rt-format库的各种用法,包括:

  1. 基本字符串格式化
  2. 数字精度控制
  3. 命名参数的使用
  4. 运行时动态构建格式化字符串
  5. 高级用法:预解析格式字符串以提高性能

输出结果将是:

基本格式化: Hello, world!
数字格式化: 圆周率: 3.14
命名参数格式化: Rust编程书价格: 99.99元,库存: 100件
动态格式化: 用户张三的午餐消费了28.50元
预解析格式化: 日期: 2023-08-15

1 回复

Rust文本格式化库rt-format的使用指南

rt-format是一个高效灵活的Rust字符串与数据格式化工具库,提供了比标准库更丰富的格式化功能。

基本特性

  • 高性能的字符串格式化
  • 支持复杂的数据格式化需求
  • 灵活的占位符系统
  • 可扩展的格式化器接口

安装

在Cargo.toml中添加依赖:

[dependencies]
rt-format = "0.3"

基本使用

简单格式化

use rt_format::{format, Format};

let name = "Alice";
let age = 30;
let formatted = format!("Hello, {name}! You are {age} years old.");
println!("{}", formatted);

数字格式化

use rt_format::{format, Format};

let number = 1234.5678;
println!("{}", format!("{number:.2}"));  // 输出: 1234.57
println!("{}", format!("{number:,}"));   // 输出: 1,234.5678

高级功能

自定义格式化

use rt_format::{format, Format, Formatter, Argument};

struct Point {
    x: i32,
    y: i32,
}

impl Format for Point {
    fn format(&self, f: &mut Formatter) {
        write!(f, "({}, {})", self.x, self.y);
    }
}

let p = Point { x: 10, y: 20 };
println!("{}", format!("Point: {p}"));  // 输出: Point: (10, 20)

条件格式化

use rt_format::{format, Format};

let value = 42;
println!("{}", format!("The value is {value:?if value > 50:'large'|'small'}"));
// 输出: The value is small

复数处理

use rt_format::{format, Format};

let count = 1;
println!("{}", format!("You have {count} item{count:s}"));
// 输出: You have 1 item

let count = 5;
println!("{}", format!("You have {count} item{count:s}"));
// 输出: You have 5 items

性能优化

rt-format在设计上考虑了性能,对于大多数用例,它的性能接近或等同于标准库的格式化功能。对于高性能场景,可以使用预编译的格式化模板:

use rt_format::{ParsedFormat, Format};

let template = ParsedFormat::new("Hello, {name}! Today is {day}.").unwrap();

let formatted = template.format(&[
    ("name", "Alice").into(),
    ("day", "Monday").into(),
]);

println!("{}", formatted);

完整示例

下面是一个结合了rt-format多种功能的完整示例:

use rt_format::{format, Format, Formatter, Argument, ParsedFormat};

// 自定义结构体格式化
struct User {
    name: String,
    age: u32,
    points: Vec<Point>,
}

struct Point {
    x: i32,
    y: i32,
}

impl Format for Point {
    fn format(&self, f: &mut Formatter) {
        write!(f, "({}, {})", self.x, self.y);
    }
}

impl Format for User {
    fn format(&self, f: &mut Formatter) {
        write!(f, "{} ({}岁)", self.name, self.age);
        if !self.points.is_empty() {
            write!(f, " [");
            for (i, point) in self.points.iter().enumerate() {
                if i > 0 {
                    write!(f, ", ");
                }
                write!(f, "{}", point);
            }
            write!(f, "]");
        }
    }
}

fn main() {
    // 简单格式化
    let name = "Bob";
    let age = 25;
    println!("{}", format!("用户: {name}, 年龄: {age}"));
    
    // 数字格式化
    let price = 12345.6789;
    println!("{}", format!("价格: {price:.2}"));
    println!("{}", format!("价格(带千位分隔符): {price:,}"));
    
    // 自定义格式化
    let user = User {
        name: "Charlie".to_string(),
        age: 35,
        points: vec![
            Point { x: 10, y: 20 },
            Point { x: 30, y: 40 },
        ],
    };
    println!("{}", format!("用户信息: {user}"));
    
    // 条件格式化
    let score = 85;
    println!("{}", format!("成绩: {score:?if score >= 90:'优秀'|score >= 60:'及格'|'不及格'}"));
    
    // 复数处理
    let item_count = 1;
    println!("{}", format!("你有{item_count}个物品{item_count:s}"));
    let item_count = 5;
    println!("{}", format!("你有{item_count}个物品{item_count:s}"));
    
    // 预编译模板
    let template = ParsedFormat::new("欢迎{user},今天是{day}").unwrap();
    let formatted = template.format(&[
        ("user", "David").into(),
        ("day", "星期二").into(),
    ]);
    println!("{}", formatted);
}

总结

rt-format为Rust开发者提供了:

  1. 更丰富的格式化选项
  2. 更高的灵活性
  3. 良好的性能表现
  4. 可扩展的格式化系统

适用于需要复杂格式化逻辑或对标准库格式化功能感到受限的场景。

回到顶部