Rust 语法
现在你已经能运行 Rust 程序了,接下来放慢脚步,看看程序的每个部分到底是什么意思。我们用一个最小的例子,把它一块一块拆开来看。
fn main() { println!("你好,世界!");}输出:
你好,世界!main 函数
Section titled “main 函数”fn main() { // 你的代码在这里运行}每个 Rust 程序都从一个名为 main 的函数开始。运行程序时,Rust 会找到 main,然后执行它里面的代码。
fn是定义函数(一段有名字的代码)的关键字。main是函数名。这个名字很特殊:它是程序的入口。()里放函数的输入(这里是空的,main不接收任何输入)。- 花括号
{ }包住的是函数体,也就是属于这个函数的代码。
语句以分号结尾
Section titled “语句以分号结尾”在函数体里,每条指令通常是一条语句(statement),语句以分号 ; 结尾:
fn main() { let x = 5; let y = 10; println!("{}", x + y);}输出:
15在该加分号的地方漏掉分号,是新手最常犯的错误之一。不过别担心,编译器会直接指出问题在哪儿。
表达式:会返回值的代码
Section titled “表达式:会返回值的代码”Rust 代码由两种成分组成,而且这两者的区别在 Rust 里比在大多数语言里都重要:
- 语句会执行某个操作,但不返回值。
let x = 5;就是一条语句。 - 表达式(expression)会产生一个值。
5、x + 1和x * 2都是表达式。
接下来这一点常常让人意外:用花括号 { } 括起来的代码块也是一个表达式。它的值就是最后一行,而且这一行不写分号:
fn main() { let x = 5; let y = { let doubled = x * 2; // 代码块里的一条语句 doubled + 1 // 没有分号:这就是代码块的值 }; println!("y 是 {y}");}输出:
y 是 11这个代码块先执行里面的语句,再交出 doubled + 1 的结果,也就是 11,于是 y 就等于 11。注意右花括号 } 后面的分号:整行 let y = ...; 仍然是一条语句。
如果在 doubled + 1 后面加上分号,它就不再是代码块的值了。这时代码块返回的是“什么都没有”(Rust 把它写作 ()),而 println! 没法打印它,所以代码无法编译。“最后一行不写分号”这条规则,正是函数返回值的方式。你会在函数一页和把 if 当作表达式时再次见到它。
仔细看 println!:那个感叹号不是笔误。! 表示它是一个宏(macro),而不是普通函数。
现在还不用完全弄懂宏。只要记住一点:看到 !,就说明是宏。目前你唯一会用到的宏,就是用来打印文字的 println!。
fn main() { println!("这是一次宏调用");}用 {} 打印值
Section titled “用 {} 打印值”在 println! 里,花括号 {} 是占位符,会被你写在文字后面的值依次填上:
fn main() { let name = "Ferris"; let age = 10; println!("{} 今年 {} 岁", name, age);}输出:
Ferris 今年 10 岁也可以把变量名直接写在花括号里,这样通常更清爽:
println!("{name} 今年 {age} 岁");Rust 不像 Python 那样在意缩进。它靠花括号 { } 来判断代码块从哪里开始、到哪里结束。缩进只是为了让人更容易读懂代码。
话虽如此,Rust 社区有一套标准风格,而且 Rust 自带一个工具,可以自动把代码整理成这种风格:
cargo fmt运行 cargo fmt 会把你的代码重新排版成官方风格。养成经常用它的习惯吧。
你可以在代码里留下一些 Rust 会忽略的说明文字。这就是注释,以 // 开头:
fn main() { // 这是一条注释,Rust 会跳过它 println!("你好!"); // 注释也可以写在行尾}下一页会更详细地讲注释。
1. 把算式打印出来
Section titled “1. 把算式打印出来”创建两个变量 a = 7 和 b = 3,打印出 7 + 3 = 10。加法让 Rust 来算。提示:一个 println! 可以有多个 {} 占位符,会按顺序用文字后面的值填上。
2. 用代码块计算总价
Section titled “2. 用代码块计算总价”一家店卖 3 件商品,每件 4 元,另加 2 元运费。用一个 { } 代码块计算 total:在块里先算出 subtotal,再交出 subtotal + 2。打印 总价:14。提示:代码块的最后一行不能有分号。
查看答案
fn main() { let price = 4; let quantity = 3; let total = { let subtotal = price * quantity; subtotal + 2 // 运费 }; println!("总价:{total}");}输出:
总价:14- 每个程序都从
main函数开始。 - 代码写在花括号
{ }里;大多数语句以;结尾。 - 语句执行操作;表达式产生值。代码块中不带
;的最后一行就是它的值。 - 带
!的(比如println!)是宏。 println!里的{}是占位符,由你传入的值来填充。- 缩进是为了可读性,运行
cargo fmt可以自动格式化。
小测验
1. 在 Rust 程序里,main 函数有什么特别之处?
2. println 后面的 ! 是什么意思?
3. 执行 let y = { let a = 2; a + 1 }; 之后,y 的值是多少?
得分: 0 / 3
- Rust 程序的结构 —《Rust 程序设计语言》:官方教程对
fn main、println!和分号的逐步讲解。 - 语句和表达式 —《Rust 程序设计语言》:更多区分语句与表达式的例子,包括代码块。
- Hello World —《通过例子学 Rust》:一个可以运行的小程序,以及如何直接用
rustc编译它。 - 表达式 —《通过例子学 Rust》:把代码块当作值来用的简短示例,以及末尾加分号会发生什么。
- Statements and expressions — The Rust Reference(英文):精确、正式的规则,等你以后好奇时再看。