Rust动态格式化库dyn-fmt的使用,dyn-fmt提供运行时字符串格式化与模板渲染功能
dyn-fmt
提供动态字符串格式化功能。
use dyn_fmt::AsStrFormatExt;
fn main() {
assert_eq!("{}a{}b{}c".format(&[1, 2, 3]), "1a2b3c");
assert_eq!("{}a{}b{}c".format(&[1, 2, 3, 4]), "1a2b3c");
assert_eq!("{}a{}b{}c".format(&[1, 2]), "1a2bc");
assert_eq!("{{}}{}".format(&[1, 2]), "{}1");
}
比较
dyn-fmt | strfmt | dynfmt | |
---|---|---|---|
no_std | + | - | - |
简单但强大的API,使用愉快 | + | +/- | - |
良好的许可证 | + | +/- | +/- |
完整示例代码:
// 引入dyn-fmt库
use dyn_fmt::AsStrFormatExt;
fn main() {
// 基本格式化示例
let formatted = "Hello, {}! Today is {}.".format(&["World", "Monday"]);
println!("{}", formatted); // 输出: Hello, World! Today is Monday.
// 处理多余参数
let result = "Numbers: {}, {}, {}".format(&[1, 2, 3, 4, 5]);
println!("{}", result); // 输出: Numbers: 1, 2, 3
// 处理参数不足
let partial = "Values: {}, {}, {}".format(&[10, 20]);
println!("{}", partial); // 输出: Values: 10, 20,
// 转义大括号
let escaped = "Escaped: {{}} and {}".format(&["replacement"]);
println!("{}", escaped); // 输出: Escaped: {} and replacement
// 使用不同类型的值
let mixed = "Int: {}, Float: {}, Str: {}".format(&[42, 3.14, "test"]);
println!("{}", mixed); // 输出: Int: 42, Float: 3.14, Str: test
}
1 回复
Rust动态格式化库dyn-fmt的使用指南
概述
dyn-fmt是一个Rust动态格式化库,提供运行时字符串格式化和模板渲染功能。与Rust标准库的format!宏不同,dyn-fmt允许在运行时动态指定格式化模板和参数,特别适合需要从配置文件、用户输入或其他外部源加载模板的场景。
主要特性
- 运行时模板解析和格式化
- 支持位置参数和命名参数
- 轻量级且无依赖
- 与标准库格式化语法兼容
安装方法
在Cargo.toml中添加依赖:
[dependencies]
dyn-fmt = "0.3"
基本用法
1. 使用位置参数
use dyn_fmt::AsStrFormatExt;
fn main() {
let template = "Hello, {}! Today is {}.";
let formatted = template.format(&["World", "Monday"]);
println!("{}", formatted); // 输出: Hello, World! Today is Monday.
}
2. 使用命名参数
use dyn_fmt::AsStrFormatExt;
fn main() {
let template = "User: {name}, Age: {age}, City: {city}";
let params = [
("name", "Alice"),
("age", "25"),
("city", "New York")
];
let formatted = template.format(¶ms);
println!("{}", formatted); // 输出: User: Alice, Age: 25, City: New York
}
3. 混合使用位置和命名参数
use dyn_fmt::AsStrFormatExt;
fn main() {
let template = "{}: {name} scored {score} points";
let params = [
("0", "Game1"), // 位置参数
("name", "PlayerA"), // 命名参数
("score", "100") // 命名参数
];
let formatted = template.format(¶ms);
println!("{}", formatted); // 输出: Game1: PlayerA scored 100 points
}
高级用法
1. 从文件加载模板
use dyn_fmt::AsStrFormatExt;
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let template = fs::read_to_string("template.txt")?;
let data = [
("title", "Rust Programming"),
("author", "Mozilla"),
("year", "2023")
];
let content = template.format(&data);
println!("{}", content);
Ok(())
}
2. 动态构建参数列表
use dyn_fmt::AsStrFormatExt;
fn format_user_data(name: &str, email: &str, age: u32) -> String {
let template = "Name: {name}\nEmail: {email}\nAge: {age}";
let params = [
("name", name),
("email", email),
("age", &age.to_string())
];
template.format(¶ms)
}
fn main() {
let result = format_user_data("Bob", "bob@example.com", 30);
println!("{}", result);
}
错误处理
dyn-fmt会在格式化失败时返回错误而不是panic:
use dyn_fmt::AsStrFormatExt;
fn safe_format(template: &str, params: &[(&str, &str)]) -> Result<String, dyn_fmt::FormatError> {
template.try_format(params)
}
fn main() {
let result = safe_format("Hello {name}", &[("wrong_key", "value")]);
match result {
Ok(s) => println!("Success: {}", s),
Err(e) => println!("Error: {}", e),
}
}
性能提示
- 对于需要重复使用的模板,考虑缓存格式化结果
- 在性能关键路径上,尽量避免频繁的字符串分配
- 使用
try_format
进行错误检查而不是直接使用format
这个库为需要运行时格式化的场景提供了灵活的解决方案,特别适合Web模板、日志格式化和配置驱动的文本生成等应用场景。
完整示例demo
// 完整示例:演示dyn-fmt库的各种用法
use dyn_fmt::AsStrFormatExt;
use std::fs;
use std::collections::HashMap;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例1:基本位置参数
println!("=== 基本位置参数示例 ===");
let template1 = "欢迎来到{},今天是{},天气{}";
let result1 = template1.format(&["北京", "星期一", "晴朗"]);
println!("{}", result1);
// 示例2:命名参数
println!("\n=== 命名参数示例 ===");
let template2 = "产品名称:{name},价格:{price}元,库存:{stock}件";
let params2 = [
("name", "Rust编程书"),
("price", "99"),
("stock", "50")
];
let result2 = template2.format(¶ms2);
println!("{}", result2);
// 示例3:混合参数
println!("\n=== 混合参数示例 ===");
let template3 = "订单{}:客户{name}购买了{product},总价{price}元";
let params3 = [
("0", "20231001"), // 位置参数
("name", "张三"), // 命名参数
("product", "笔记本电脑"), // 命名参数
("price", "5999") // 命名参数
];
let result3 = template3.format(¶ms3);
println!("{}", result3);
// 示例4:从文件读取模板
println!("\n=== 文件模板示例 ===");
// 假设template.txt内容为:"文章标题:{title}\n作者:{author}\n发布时间:{date}"
let template_content = "文章标题:{title}\n作者:{author}\n发布时间:{date}";
let article_data = [
("title", "Rust语言入门指南"),
("author", "技术社区"),
("date", "2023-10-01")
];
let article_content = template_content.format(&article_data);
println!("{}", article_content);
// 示例5:错误处理
println!("\n=== 错误处理示例 ===");
let error_template = "Hello {username}";
let error_params = [("wrong_key", "value")];
match error_template.try_format(&error_params) {
Ok(s) => println!("成功: {}", s),
Err(e) => println!("错误: {}", e),
}
// 示例6:动态构建复杂参数
println!("\n=== 动态参数构建示例 ===");
let user_info = format_user_profile("李四", "lisi@example.com", 28, "上海");
println!("{}", user_info);
Ok(())
}
// 动态构建用户信息
fn format_user_profile(name: &str, email: &str, age: u32, city: &str) -> String {
let template = "用户信息:\n姓名:{name}\n邮箱:{email}\n年龄:{age}\n城市:{city}";
// 动态构建参数数组
let params = [
("name", name),
("email", email),
("age", &age.to_string()),
("city", city)
];
template.format(¶ms)
}
// 使用HashMap构建参数的替代方法
fn format_with_hashmap() -> String {
let template = "配置信息:\n服务器:{host}\n端口:{port}\n数据库:{db}";
let mut params_map = HashMap::new();
params_map.insert("host", "localhost");
params_map.insert("port", "5432");
params_map.insert("db", "postgres");
// 将HashMap转换为数组切片
let params: Vec<(&str, &str)> = params_map.iter()
.map(|(k, v)| (k.as_str(), *v))
.collect();
template.format(¶ms)
}
这个完整示例演示了dyn-fmt库的主要功能,包括基本的位置参数和命名参数使用、混合参数、错误处理以及动态参数构建。示例代码包含了详细的注释,帮助理解每个功能的使用方法。