From 9b1f5ee49eebb5a1894701ed2e4e63453016e7c6 Mon Sep 17 00:00:00 2001 From: Hector PENG Date: Sat, 7 Mar 2026 16:55:44 +0800 Subject: [PATCH] Updated src/programming_concepts/functions.md'. --- README.md | 2 +- projects/expressions/Cargo.toml | 6 + projects/expressions/src/main.rs | 8 + projects/functions/Cargo.toml | 4 +- src/Ch00_Forword_and_Introduction.md | 4 +- src/Ch02_Programming_a_Guessing_Game.md | 12 +- src/programming_concepts/functions.md | 209 ++++++++++++------------ 7 files changed, 126 insertions(+), 119 deletions(-) create mode 100644 projects/expressions/Cargo.toml create mode 100644 projects/expressions/src/main.rs diff --git a/README.md b/README.md index 8798bcf..7f9cc5b 100644 --- a/README.md +++ b/README.md @@ -132,5 +132,5 @@ Rust 语言希望也能支持许多其他用户;这里提到的只是一些最 ## 本书的源码 -本书所产生的源码,可在 [Github: gnu4cn/rust-lang](https://github.com/gnu4cn/rust-lang-zh_CN/projects) 下载到。 +本书所产生的源码,可在 [Github: gnu4cn/rust-lang](https://github.com/gnu4cn/rust-lang-zh_CN/tree/main/projects) 下载到。 diff --git a/projects/expressions/Cargo.toml b/projects/expressions/Cargo.toml new file mode 100644 index 0000000..be2a755 --- /dev/null +++ b/projects/expressions/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "expressions" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/projects/expressions/src/main.rs b/projects/expressions/src/main.rs new file mode 100644 index 0000000..50b8559 --- /dev/null +++ b/projects/expressions/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + let y = { + let x = 3; + x + 1; + }; + + println! ("y 的值为:{:?}", y); +} diff --git a/projects/functions/Cargo.toml b/projects/functions/Cargo.toml index a9b5578..9c392ab 100644 --- a/projects/functions/Cargo.toml +++ b/projects/functions/Cargo.toml @@ -1,8 +1,6 @@ [package] name = "functions" version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +edition = "2024" [dependencies] diff --git a/src/Ch00_Forword_and_Introduction.md b/src/Ch00_Forword_and_Introduction.md index fece7f2..9d0d2fa 100644 --- a/src/Ch00_Forword_and_Introduction.md +++ b/src/Ch00_Forword_and_Introduction.md @@ -126,13 +126,13 @@ Rust 语言希望也能支持许多其他用户;这里提到的只是一些最 阅读本书并无定法:你要跳着去读,也是可以的!在遇到疑惑时,或许就不得不跳回去看看了。你只要怎么有效就行了。 -学习 Rust 过程中的一个重要部分是学习如何阅读编译器给出的错误信息:这些信息将指导咱们编写工作的代码。因此,我们将提供许多不能编译的例子,以及编译器在每种情况下显示的错误信息。要知道,如果咱们随便输入并运行一个例子,他可能不会被编译!请确保咱们阅读报错周围的文字,看看咱们试图运行的例子是否会出错。 +学习 Rust 过程中的一个重要部分是学习如何阅读编译器给出的错误信息:这些信息将指导咱们编写出工作的代码。因此,我们将提供许多不能编译的例子,以及编译器在每种情况下显示的错误信息。要知道,如果咱们随便输入并运行一个例子,他可能不会被编译!请确保咱们阅读报错周围的文字,看看咱们试图运行的例子是否会出错。 在大多数情况下,我们会带着找到任何不能编译的代码的正确版本。 ## 本书的源码 -本书所产生的源码,可在 [Github: gnu4cn/rust-lang](https://github.com/gnu4cn/rust-lang-zh_CN/projects) 下载到。 +本书所产生的源码,可在 [Github: gnu4cn/rust-lang](https://github.com/gnu4cn/rust-lang-zh_CN/tree/main/projects) 下载到。 (End) diff --git a/src/Ch02_Programming_a_Guessing_Game.md b/src/Ch02_Programming_a_Guessing_Game.md index cba4253..0755072 100644 --- a/src/Ch02_Programming_a_Guessing_Game.md +++ b/src/Ch02_Programming_a_Guessing_Game.md @@ -100,7 +100,7 @@ fn main() { } ``` - + *清单 2-1,从用户处获取一个猜数并将其打印出来的代码* 这段代码包含了大量信息,所以我们来逐行查看。要获取用户输入,然后将结果作为输出打印,我们就需要将 `io` 这个输入/输出库,带入作用域。`io` 库来自标准库,称为 `std`: @@ -360,7 +360,7 @@ remote: Total 1043606 (delta 693593), reused 848030 (delta 620187), pack-reused Finished `dev` profile [unoptimized + debuginfo] target(s) in 9m 51s ``` - + *清单 2-2:在添加 `rand` 代码箱作为依赖项添加后,运行 `cargo build` 的输出** > **译注**:这里译者使用了国内的 `ustc` Cargo 登记簿镜像。 @@ -455,7 +455,7 @@ fn main() { } ``` - + *清单 2-3:添加生成随机数的代码* @@ -521,7 +521,7 @@ fn main() { } } ``` - + *清单 2-4:处理比较两个数字可能的返回值* @@ -756,7 +756,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace // --跳过-- ``` - + *清单 2-5:忽略非数字的猜数并请求另一猜数,而不是让崩溃程序* @@ -829,7 +829,7 @@ fn main() { } ``` - + *清单 2-6:完整的猜数游戏代码* diff --git a/src/programming_concepts/functions.md b/src/programming_concepts/functions.md index 53db55a..d87e48c 100644 --- a/src/programming_concepts/functions.md +++ b/src/programming_concepts/functions.md @@ -1,11 +1,8 @@ # 函数 -**Functions** +函数在 Rust 代码中普遍存在。咱们已经看到这门语言中最重要函数之一:`main` 函数,他是许多程序的入口点。咱们还看到了 `fn` 这个关键字,他允许咱们声明新的函数。 - -函数在 Rust 代码中非常普遍。咱们已经看到,这门语言中最重要的函数之一:`main` 函数,他是许多程序的入口点。咱们还见过 `fn` 关键字,他允许咱们声明出新的函数。 - -Rust 代码使用 *蛇形命名法,snake case*,作为函数和变量名的习惯样式,其中所有字母都是小写,并以下划线分隔单词。下面是个包含了函数定义示例的程序: +Rust 代码使用 *蛇形命名法,snake case* 作为函数和变量名字的约定样式,其中所有字母都是小写,并以下划线分隔单词。下面是个包含示例函数定义的程序: 文件名:`src/main.rs` @@ -22,33 +19,30 @@ fn another_function() { } ``` -我们通过输入后跟函数名和一组括号的 `fn`,来定义出 Rust 中的函数。花括号告诉编译器,函数体于何处开始及结束。 +我们通过输入 `fn`,后跟函数名和一组括号定义 Rust 中的某个函数。花括号告诉编译器,函数体于何处开始及结束。 -我们可以通过输入后跟一组括号的其名字,来调用我们已定义的任何函数。因为 `another_function` 是在该程序中定义的,所以可以从 `main` 函数内部调用他。请注意,我们在源代码中的 `main` 函数 *之后*,定义了 `another_function`;我们也可以在之前定义他。 Rust 并不关心咱们在何处定义函数,而只关心他们,是在调用者可以看到的作用域中某个地方定义的。 +通过输入函数名字后跟一组括号,我们便可调用我们已定义的任何函数。因为 `another_function` 定义在这个程序中,其就可从 `main` 函数内部调用。请注意,我们是在源代码中 `main` 函数 *之后* 定义的 `another_function`;我们原本也可以在之前定义他。Rust 不关心咱们于何处定义咱们的函数,而只关心他们定义在调用者可以看到的作用域中的某处。 -我们来启动一个名为 `functions` 的新二进制项目,以进一步探索函数。请将这个 `another_function` 示例,放入 `src/main.rs` 并运行。咱们会看到以下输出: +我们来启动一个名为 `functions` 的新二进制项目,进一步探讨函数。请将这个 `another_function` 示例放入 `src/main.rs` 并运行他。咱们应看到以下输出: ```console $ cargo run - Compiling functions v0.1.0 (/home/peng/rust-lang/projects/functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.32s + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s Running `target/debug/functions` Hello, world! 另一函数。 ``` -这些行会按照他们在主函数中出现的顺序执行。首先打印 "Hello, world!" 这条消息,然后 `another_function` 被调用,并打印其消息。 +这些代码行会以他们在 `main` 函数中的出现顺序执行。首先打印 `"Hello, world!"` 这条消息,然后 `another_function` 被调用并打印其消息。 ## 参数 -**Parameters** +我们可将函数定义为有着一些 *参数,parameters*,他们是属于函数签名一部分的一些特殊变量。当某个函数有着参数时,咱们就可以提供给他这些参数的具体值。技术上讲,具体值称为 *实参,arguments*,但在日常交谈中,针对函数定义中的变量,或咱们调用函数时传入的具体值,人们倾向于可互换使用 *形参,parameter* 和 *实参,argument* 这两个词。 - -我们可以将函数定义有着一些 *参数,parameters*,他们是函数签名的一部分的一些特殊变量。当某个函数有参数时,咱们就可以为这些参数,提供一些具体值。技术上讲,这些具体值被称为 *实参,arguments*,但在日常交谈中,人们倾向于可互换使用 *形参,parameter* 和 *实参,argument* 这两个词,来指代函数定义中的变量,或调用函数时传入的具体值。 - -在下面这个版本的 `another_function` 中,我们添加了一个参数: +在下面这个版本的 `another_function` 中,我们添加了个参数: 文件名:`src/main.rs` @@ -63,23 +57,23 @@ fn another_function(x: i32) { ``` -请尝试运行这个程序;咱们应得到以下输出: +尝试运行这个程序;咱们应得到以下输出: ```console $ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.88s - Running `target\debug\functions.exe` + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s + Running `target/debug/functions` x 的值为:-5 ``` -`another_function` 的声明,有个名为 `x` 的参数。`x` 的类型,被指定为了 `i32`。当我们将 `5` 传入到 `another_function` 时,`println!` 这个宏,会将 `5` 在格式字符串中,原先那个包含 `x` 的一对大括号处。 +`another_function` 的声明有个名为 `x` 的参数。`x` 的类型被指定为 `i32`。当我们将 `-5` 传递进 `another_function` 时,`println!` 这个宏就会将 `5` 在格式字符串中,原先包含着 `x` 的一对大括号处。 -在函数签名中,我们 *必须* 声明出每个参数的类型。这是 Rust 设计中的一个深思熟虑的决定:要求在函数定义中进行类型注解,意味着编译器几乎永远不需要咱们,在代码的其他地方,使用类型注解来确定咱们所指的是何种类型。如果编译器知道函数所期望的类型,他还能给出更有用的错误信息。 +在函数签名中,我们 *必须* 声明每个参数的类型。这是 Rust 设计中的一个深思熟虑的决定:在函数定义中要求类型注解,意味着编译器几乎永远不需要咱们在代码的其他地方,使用类型注解确定出咱们所指的是何种类型。当编译器清楚函数所期望的类型时,他还能够给到更有用的错误消息。 -定义多个参数时,请用逗号分隔参数声明,如下所示: +在定义多个参数时,要以逗号分隔这些参数声明,如下所示: 文件名:`src/main.rs` @@ -94,40 +88,34 @@ fn print_labeled_measurement(value: i32, unit_label: char) { } ``` +这个示例创建了个名为 `print_labeled_measurement`,有着两个参数的函数。其中第一个参数名为 `value`,是个 `i32`。第二个参数名为 `unit_label`,为 `char` 类型。这个函数随后会打印同时包含 `value` 和 `unit_label` 的文本。 -这个示例创建了一个名为 `print_labeled_measurement`,有着两个参数的函数。其中第一个参数名为 `value`,是个 `i32`。第二个参数名为 `unit_label`,类型为 `char`。该函数随后会打印同时包含 `value` 和 `unit_label` 的文本。 - -我们来尝试运行这段代码。请用前面的示例,替换 `functions` 项目的 `src/main.rs` 文件中当前的程序,然后使用 `cargo run` 运行他: - +我们来尝试运行这段代码。请以前面的示例替换当前咱们 `functions` 项目的 `src/main.rs` 文件中的程序,并使用 `cargo run` 运行他: ```console $ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.58s - Running `target\debug\functions.exe` + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s + Running `target/debug/functions` 度量值为:5h ``` - -因为我们使用 `5` 作为 `value` 的值、`'h'` 作为 `unit_label` 的值,调用了该函数,所以程序输出会包含这些值。 +因为我们以 `5` 作为 `value` 的值、`'h'` 作为 `unit_label` 的值调用了该函数,所以这个程序输出会包含这两个值。 ## 语句及表达式 -**Statements and Expressions** - - -函数体由一系列语句组成,可选择以表达式结束。到目前为止,我们所涉及的函数,还未包含结束表达式,an ending expression,但我们已经看到,作为语句一部分的表达式。因为 Rust 是门基于表达式的语言,所以理解这一点很重要。其他语言没有这同一区别,因此我们来看看,什么是语句和表达式,以及他们的区别如何影响函数的主体。 - - -- **语句,statements**,是执行某些操作,但不返回值的指令; - -- **表达式,expressions**,会求得一个结果值。咱们来一些示例。 - - -实际上,我们已经使用过语句和表达式。使用 `let` 关键字创建变量并赋个值给他,就是语句。在下清单 3-1 中,`let y = 6;` 就是条语句。 +函数体由一系列可选地以一个表达式结束的语句组成。到目前为止,我们介绍的函数都还未包含一个结束表达式,an ending expression,但我们已经看到,作为语句一部分的表达式。因为 Rust 是门基于表达式的语言,an expression-based language,所以这是个要掌握的重要区别。别的语言没有这相同区别,因此我们来看看,什么是语句和表达式,以及他们的区别如何影响函数的主体。 + +- 所谓 *语句,statements*,属于一些会执行某些操作,但不返回值的指令; +- 所谓 *表达式,expressions*,会计算为某个结果值。 + +咱们来看一些示例。 + +我们实际上已经用到了语句和表达式。以 `let` 关键字创建某个变量并赋值给他就是一条语句。在下清单 3-1 中,`let y = 6;` 就是条语句。 + 文件名:`src/main.rs` ```rust @@ -136,12 +124,12 @@ fn main() { } ``` -*清单 3-1:包含一条语句的一个 `main` 函数* +*清单 3-1:包含一条语句的 `main` 函数声明* -函数定义也是语句;上面的整个示例本身就是一条语句。 +函数定义也属于语句;整个上面的示例本身就是条语句。 -语句不返回值。因此,咱们不能将 `let` 语句,赋值给另一个变量,就像下面的代码试图做的那样;咱们会得到一个报错: +语句不会返回值。因此,咱们不能将某个 `let` 语句赋值给另一变量,就像以下代码试图做的那样;咱们将得到一个报错: 文件名:`src/main.rs` @@ -152,15 +140,13 @@ fn main() { } ``` - -当咱们运行这个程序时,咱们将得到的报错,会看起来像下面这样: - +当咱们运行这个程序时,咱们将得到的报错会看起来如下: ```console $ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) error: expected expression, found `let` statement - --> src\main.rs:2:14 + --> src/main.rs:2:14 | 2 | let x = (let y = 6); | ^^^ @@ -168,28 +154,25 @@ error: expected expression, found `let` statement = note: only supported directly in conditions of `if` and `while` expressions warning: unnecessary parentheses around assigned value - --> src\main.rs:2:13 + --> src/main.rs:2:13 | 2 | let x = (let y = 6); | ^ ^ | - = note: `#[warn(unused_parens)]` on by default + = note: `#[warn(unused_parens)]` (part of `#[warn(unused)]`) on by default help: remove these parentheses | 2 - let x = (let y = 6); -2 + let x = let y = 6; +2 + let x = let y = 6 ; | warning: `functions` (bin "functions") generated 1 warning -error: could not compile `functions` (bin "functions") due to previous error; 1 warning emitted +error: could not compile `functions` (bin "functions") due to 1 previous error; 1 warning emitted ``` +其中 `let y = 6` 语句不会返回值,因此没有 `x` 要绑定任何东西。这与别的语言(如 C 和 Ruby)中发生的情况,在其他语言中,赋值会返回这一赋值的值。在这些语言中,咱们可以写下 `x = y = 6`,而让 `x` 和 `y` 都有着 `6` 这个值; Rust 中的情况并非如此。 -其中的 `let y = 6` 语句不会返回值,因此 `x` 没有任何绑定对象。这与其他语言(如 C 和 Ruby)的情况不同,在其他语言中,赋值会返回赋值的值。在这些语言中,咱们可以写下 `x = y = 6`,而 `x` 和 `y`,都会有着值 `6`;而在 Rust 中,情况并非如此。 - -表达式会计算为一个值,并构成咱们在 Rust 中,将编写的其余代码的大部分。请设想某个数学运算,例如 `5 + 6`,这是个会求值为 `11` 的表达式。表达式可以是语句的一部分:在清单 3-1 中,语句 `let y = 6;` 中的 `6`,是个求值为 `6` 的表达式。调用某个函数,便是个表达式。调用某个宏,是个表达式。用花括号创建的某个新作用域块,是个表达式,比如: - -表达式可作为语句的一部分:在清单 3-1 中,语句 `let y = 6;` 里的 `6` 就是一个求值到 `6` 的表达式。对函数的调用,同样是个表达式。对宏的调用,也是个表达式。以花括号创建出的新代码块,还是个表达式,比如: +表达式会计算为某个值,并构成咱们将以 Rust 编写的其余大部分代码。请设想某一数学运算,例如 `5 + 6`,其就是个会求值为 `11` 的表达式。表达式可以是语句的一部分:在清单 3-1 中,语句 `let y = 6;` 中的 `6` 就是个会求值为 `6` 的表达式;调用函数属于表达式;调用宏属于表达式;以花括号创建出的新作用域块属于表达式,例如: 文件名:`src/main.rs` @@ -205,50 +188,65 @@ fn main() { } ``` -其中这个表达式: +其中这一表达式: ```rust -{ - let x = 3; - x + 1 -} + { + let x = 3; + x + 1 + } ``` -是个在本示例种,会求值为 `4` 的一个代码块。该值会作为那个 `let` 语句的一部分,被绑定到 `y`。请注意,`x + 1` 这行的结尾,没有分号,这与咱们目前看到的大多数行不同。表达式不会包括结尾的分号。如果咱们在表达式的末尾加上分号,咱们便将其转换为了语句,而他就将不返回值。在接下来咱们探讨函数返回值和表达式时,请牢记这一点。 +在这种情况下就是个会求值为 `4` 的代码块。该值会作为其中 `let` 语句的一部分被绑定到 `y`。请注意那个结束处没有分号的 `x + 1` 行,这与咱们到目前为止看到的大多数行都不同。表达式不会包含结束分号。当咱们添加一个分号到表达式末尾时,咱们便将其转换为了语句,而他将不返回值。在接下来咱们探讨函数的返回值与表达式时,要牢记这点。 -> 注:若在上面代码块中的 `x + 1` 后面加上分号,那么 `y` 的值将为 *单元值,unit* `()` 这一特殊值。进而在接下来的 `println!` 语句中导致出错。 - - -```console -$ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) -error[E0277]: `()` doesn't implement `std::fmt::Display` - --> src\main.rs:7:22 - | -7 | println! ("y 的值为:{y}"); - | ^^^ `()` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `()` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly - builds, run with -Z macro-backtrace for more info) - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `functions` (bin "functions") due to previous error -``` +> **译注**:若在上面代码块中的 `x + 1` 后面加上分号,那么 `y` 的值将为 *单元值,unit* `()` 这一特殊值。进而在接下来的 `println!` 语句中导致出错。 +> +> +> ```console +> $ cargo run +> Compiling expressions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/expressions) +> error[E0277]: `()` doesn't implement `std::fmt::Display` +> --> src/main.rs:7:27 +> | +> 4 | x + 1; +> | - help: remove this semicolon +> ... +> 7 | println! ("y 的值为:{}", y); +> | -- ^ `()` cannot be formatted with the default formatter +> | | +> | required by this formatting parameter +> | +> = help: the trait `std::fmt::Display` is not implemented for `()` +> = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +> = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +> +> For more information about this error, try `rustc --explain E0277`. +> error: could not compile `expressions` (bin "expressions") due to 1 previous error +> ``` +> +> 修改为下面这样即可输出变量 `y` 中包含的单元值: +> +> ```rust +> fn main() { +> let y = { +> let x = 3; +> x + 1; +> }; +> +> println! ("y 的值为:{:?}", y); +> } +> ``` ## 有返回值的函数 -**Functions with Return Values** + +函数可以返回值给调用他们的代码。我们不会命名返回值,但我们必须在一个箭头 (`->`) 后声明他们的类型。在 Rust 中,函数的返回值与函数体代码块中最后一个表达式的值同义。咱们可通过使用 `return` 关键字并指定某个值在函数中提前返回,但大多数函数都会隐式地返回最后一个表达式。下面是个返回了一个值的函数示例: -函数可以将一些值,返回给调用他们的代码。我们不会给返回值命名,但必须在一个箭头 (`->`) 后,声明他们的类型。在 Rust 中,函数的返回值,与函数体代码块中,最后一个表达式的值同义。咱们可以通过使用 `return` 关键字,并指定某个值来提前从函数中返回,但大多数函数,都是隐式地返回最后一个表达式。下面是个会返回值的函数示例: - - -> 注:关键字 `return` 的使用,标志着函数体的结束,`return` 语句之后的代码,将不再执行。 +> **译注**:关键字 `return` 的使用,标志着函数体的结束。`return` 语句之后的代码,将不再执行。 文件名:`src/main.rs` @@ -266,27 +264,25 @@ fn main() { ``` -在函数 `five` 中没有函数调用、宏,甚至没有 `let` 语句,就只有数字 `5` 本身。这在 Rust 中,是个完全有效的函数。请注意,该函数的返回类型也被指定了出来,为 `-> i32`。请尝试运行这段代码,输出应是下面这样: +在函数 `five` 中没有函数调用、宏,甚至没有 `let` 语句 -- 只有数字 `5` 本身。这在 Rust 中是个完全有效的函数。请注意,这个函数的返回类型也被指定了,为 `-> i32`。请尝试运行这段代码,输出应看起来像下面这样: ```console $ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.79s - Running `target\debug\functions.exe` + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s + Running `target/debug/functions` x 的值为:5 ``` -`five` 中的 `5`,便是该函数的返回值,这就是返回类型为 `i32` 的原因。我们来详细研究一下。有两个要点:首先,`let x = five();` 这行表明,我们正使用某个函数的返回值,来初始化一个变量。因为函数 `five` 的返回值是 `5`,所以这行与下面的行相同: - +`five` 中的 `5` 即为该函数的返回值,这就是返回类型为 `i32` 的原因。我们来更详细的研究一下这点。这里有两个重点:首先,`let x = five();` 这行表明,我们正使用某个函数的返回值来初始化一个变量。因为函数 `five` 会返回值一个 `5`,所以这行以下的行相同: ```rust let x = 5; ``` - -其次,`five` 这个函数没有参数,并定义了返回值的类型,但函数体是个没有分号的孤零零的 `5`,因为他是个我们要返回其值的表达式。 +其次,`five` 这个函数没有参数并定义了返回值的类型,但该函数的主体是个没有分号的孤零零的 `5`,因为他是个我们打算返回其值的表达式。 咱们来看看另一示例: @@ -306,8 +302,7 @@ fn plus_one(x: i32) -> i32 { } ``` - -运行这段代码将打印出 `x 的值为:6`。但如果我们在包含 `x + 1` 那行结束处,加个分号,而将其从表达式改为语句,咱们将得到一个报错: +运行这段代码将打印 `x 的值为:6`。但当我们在包含 `x + 1` 那行的结束处加个分号,将其从表达式改为语句时,会发生什么呢? 文件名:`src/main.rs` @@ -325,14 +320,14 @@ fn plus_one(x: i32) -> i32 { ``` -编译这段代码,会产生一条报错,如下所示: +编译这段代码会产生一个报错,如下所示: ```console $ cargo run - Compiling functions v0.1.0 (C:\tools\msys64\home\Lenny.Peng\rust-lang-zh_CN\projects\functions) + Compiling functions v0.1.0 (/home/hector/rust-lang-zh_CN/projects/functions) error[E0308]: mismatched types - --> src\main.rs:7:24 + --> src/main.rs:7:24 | 7 | fn plus_one(x: i32) -> i32 { | -------- ^^^ expected `i32`, found `()` @@ -342,11 +337,11 @@ error[E0308]: mismatched types | - help: remove this semicolon to return this value For more information about this error, try `rustc --explain E0308`. -error: could not compile `functions` (bin "functions") due to previous error +error: could not compile `functions` (bin "functions") due to 1 previous error ``` -其中的主要错误信息,`mismatched types`,揭示了这段代码的核心问题。函数 `plus_one` 的定义,说他将返回一个 `i32`,但语句不会计算为某个值,而是由 `()` 表示的单元值,the unit type。因此,没有返回任何值,这与函数定义相矛盾,而导致一个报错。在此输出中,Rust 提供了一条,可能有助于纠正此问题的信息:他建议删除分号,这就将会修复这个错误。 +其中主要报错消息,`mismatched types`,揭示了这段代码的核心问题。函数 `plus_one` 的定义表明他将返回一个 `i32` 值,但语句不会计算为某个值,而是由 `()` 表示的单元类型,the unit type。因此,没有返回任何值,这与该函数的定义相矛盾而导致错误。在这一输出中,Rust 提供了一条消息,可能有助于纠正此问题:他建议移除分号,这将会修复错误。 (End)