Rust中的花括号:如何在format!中输出{和}而不出错

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么Rust不喜欢花括号?

\n\n

如果你曾经用Rust编写过代码,并尝试通过println!输出类似{ "name": "Rust" }的内容,那么你肯定见过这个:

\n\n
println!("{ "name": "Rust" }"); // 编译错误!
\n\n

编译器会幸灾乐祸地告诉你:"invalid reference to argument 'name' — no argument named 'name' found"。然后你感到困惑:到底如何在字符串中输出花括号?在Python中,这可以通过{{ }}实现,但那里要简单得多。Rust有自己的理念:花括号不仅仅是字符,而是强大的格式化系统的一部分,这个系统借鉴自Python,但有其细微差别。

\n\n

在本文中,我们将详细讲解Rust中花括号转义的所有方法:从基本的{{ }}到使用Debug和原始字符串字面量的技巧。你将学会如何输出JSON、生成代码以及处理模板,而不会掉入编译器的陷阱。

\n\n

为什么花括号如此特殊?

\n\n

在Rust中,宏format!、println!、write!和format_args!将花括号用作占位符标记。例如:

\n\n
let name = "Rust";\nprintln!("Hello, {}!", name); // Hello, Rust!
\n\n

这里的{}是一个占位符,会被变量的值替换。但如果你需要的是{或}字符本身呢?Rust使用了一个简单的技巧:双写花括号。

\n\n

方法1:经典的双写{{和}}

\n\n

最简单且最明显的方法是连续写两个花括号。第一对{{会变成一个{,而}}会变成一个}。

\n\n

示例1:简单转义

\n
fn main() {\n    let text = format!("函数 main() {{ ... }}");\n    println!("{}", text);\n    // 输出:函数 main() { ... }\n}
\n\n

示例2:带占位符的转义

\n
fn main() {\n    let lang = "Rust";\n    let year = 2015;\n    let result = format!("{{ \\"lang\\": \\"{}\\", \\"year\\": {} }}", lang, year);\n    println!("{}", result);\n    // 输出:{ "lang": "Rust", "year": 2015 }\n}
\n\n

这个方法适用于所有地方:println!、write!、format!。记住这个规则:两个花括号 = 一个花括号。

\n\n

方法2:命名参数与转义

\n\n

如果你使用命名参数(例如{name}),转义同样有效,但需要注意花括号的位置。

\n\n

示例3:命名占位符与花括号

\n
fn main() {\n    let user = "Alice";\n    // 想要输出:你好,{Alice}!\n    println!("你好,{{{}}}!", user);\n    // 输出:你好,{Alice}!\n}
\n\n

解析字符串"你好,{{{}}}!":\n

    \n
  • {{ → 输出{
  • \n
  • {} → 替换为user
  • \n
  • }} → 输出}
  • \n
\n

\n\n

重要提示:用于转义的花括号数量始终为偶数。如果你写了{{{,那是一个错误,因为三个花括号无法形成正确的配对。

\n\n

方法3:使用Debug格式({:?})

\n\n

有时你希望输出一个数据结构,使其自动显示花括号。例如,在调试或生成JSON时。

\n\n

示例4:通过Debug输出结构体

\n
#[derive(Debug)]\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let p = Point { x: 10, y: 20 };\n    println!("{:?}", p);\n    // 输出:Point { x: 10, y: 20 }\n}
\n\n

Debug trait会自动在字段周围添加花括号。如果需要快速显示对象状态,这很方便。但如果你需要的是JSON或其他

博客

书籍推荐