From 27ce77c7f49e99d2ca5ee374868a8c6c3aa2a71a Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Wed, 1 Nov 2017 22:47:26 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E5=B0=91=E4=BA=86=E4=B8=80=E5=8D=8A*?= =?UTF-8?q?=EF=BC=8C=E6=96=9C=E4=BD=93=E6=97=A0=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch06-02-match.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch06-02-match.md b/src/ch06-02-match.md index 8829f45..f394cba 100644 --- a/src/ch06-02-match.md +++ b/src/ch06-02-match.md @@ -192,7 +192,7 @@ error[E0004]: non-exhaustive patterns: `None` not covered ``` -Rust 知道我们没有覆盖所有可能的情况甚至知道那些模式被忘记了!Rust 中的匹配是 **穷尽的**(*exhaustive):必须穷举到最后的可能性来使代码有效。特别的在这个 `Option` 的例子中,Rust 防止我们忘记明确的处理 `None` 的情况,这使我们免于假设拥有一个实际上为空的值,这造成了之前提到过的价值亿万的错误。 +Rust 知道我们没有覆盖所有可能的情况甚至知道那些模式被忘记了!Rust 中的匹配是 **穷尽的**(*exhaustive*):必须穷举到最后的可能性来使代码有效。特别的在这个 `Option` 的例子中,Rust 防止我们忘记明确的处理 `None` 的情况,这使我们免于假设拥有一个实际上为空的值,这造成了之前提到过的价值亿万的错误。 ### `_` 通配符 From 7a0df0a866b8edcb0bfe499055a2ae38803f3039 Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Tue, 7 Nov 2017 22:25:54 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E5=8E=9F=E6=96=87=E2=80=9C=E7=BB=87?= =?UTF-8?q?=E2=80=9D=E4=BC=BC=E4=B9=8E=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch07-01-mod-and-the-filesystem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-01-mod-and-the-filesystem.md b/src/ch07-01-mod-and-the-filesystem.md index a77364a..8712573 100644 --- a/src/ch07-01-mod-and-the-filesystem.md +++ b/src/ch07-01-mod-and-the-filesystem.md @@ -30,7 +30,7 @@ Cargo 创建了一个空的测试来帮助我们开始库项目,不像使用 ` 因为没有 *src/main.rs* 文件,所以没有可供 Cargo 的 `cargo run` 执行的东西。因此,我们将使用 `cargo build` 命令只是编译库 crate 的代码。 -我们将学习根据编写代码的意图来选择不同的织库项目代码组织来适应多种场景。 +我们将学习根据编写代码的意图来以不同方法组织库项目代码以适应多种情况。 ### 模块定义 From 2ef71531e3c566e5ad3de80069a8633a75e12726 Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Sat, 11 Nov 2017 13:04:53 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=80=97=E5=8F=B7?= =?UTF-8?q?=E6=96=AD=E5=8F=A5=E6=9B=B4=E5=AE=B9=E6=98=93=E7=90=86=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch08-01-vectors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index 503a786..8c3f504 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -52,7 +52,7 @@ v.push(8); } // <- v goes out of scope and is freed here ``` -当 vector 被丢弃时,所有其内容也会被丢弃,这意味着这里它包含的整数将被清理。这可能看起来非常直观,不过一旦开始使用 vector 元素的引用情况就变得有些复杂了。下面让我们处理这种情况! +当 vector 被丢弃时,所有其内容也会被丢弃,这意味着这里它包含的整数将被清理。这可能看起来非常直观,不过一旦开始使用 vector 元素的引用,情况就变得有些复杂了。下面让我们处理这种情况! ### 读取 vector 的元素 From b7d818e134deeb5b042fdaea48dcbc61037ad0df Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Sat, 11 Nov 2017 13:05:14 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch08-01-vectors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index 8c3f504..488c0eb 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -109,7 +109,7 @@ immutable | - immutable borrow ends here ``` -这些代码看起来应该能够运行:为什么第一个元素的引用会关心 vector 结尾的变化?不能这么做的原因是由于 vector 的工作方式。在 vector 的结尾增加新元素是,在没有足够空间将所有所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中。这时,第一个元素的引用就指向了被释放的内存。借用规则阻止程序陷入这种状况。 +这些代码看起来应该能够运行:为什么第一个元素的引用会关心 vector 结尾的变化?不能这么做的原因是由于 vector 的工作方式。在 vector 的结尾增加新元素时,在没有足够空间将所有所有元素依次相邻存放的情况下,可能会要求分配新内存并将老的元素拷贝到新的空间中。这时,第一个元素的引用就指向了被释放的内存。借用规则阻止程序陷入这种状况。 > 注意:关于更多内容,查看 Nomicon *https://doc.rust-lang.org/stable/nomicon/vec.html* From 1ea816f83dd5a1dfd0b0b2618c336e6541e21338 Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Sat, 11 Nov 2017 18:02:02 +0800 Subject: [PATCH 05/13] =?UTF-8?q?=E5=8E=9F=E8=AF=91=E6=96=87=E4=B8=8D?= =?UTF-8?q?=E5=A4=9F=E9=80=9A=E9=A1=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch08-02-strings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch08-02-strings.md b/src/ch08-02-strings.md index cd2e99a..9de5b41 100644 --- a/src/ch08-02-strings.md +++ b/src/ch08-02-strings.md @@ -76,7 +76,7 @@ let mut s = String::from("foo"); s.push_str("bar"); ``` -执行这两行代码之后 `s` 将会包含 “foobar”。`push_str` 方法获取字符串 slice,因为并不需要获取参数的所有权。例如,如果将 `s2` 的内容附加到 `s1` 中后自身不能被使用就糟糕了: +执行这两行代码之后 `s` 将会包含 “foobar”。`push_str` 方法获取字符串 slice,因为我们并不需要获取参数的所有权。例如,如果将 `s2` 的内容附加到 `s1` 中后自身不能被使用就糟糕了: ```rust let mut s1 = String::from("foo"); From 36cd6ff06ef27628629f2bbb934e5e416e53311f Mon Sep 17 00:00:00 2001 From: bioinformatist Date: Thu, 16 Nov 2017 20:07:26 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch09-00-error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch09-00-error-handling.md b/src/ch09-00-error-handling.md index ad93fad..609d6ee 100644 --- a/src/ch09-00-error-handling.md +++ b/src/ch09-00-error-handling.md @@ -4,7 +4,7 @@ >
> commit 4f2dc564851dc04b271a2260c834643dfd86c724 -Rust 对可靠性的执着也扩展到了错误处理。错误对于软件来说是不可避免的,所以 Rust 有很多功能来处理当现错误的情况。在很多情况下,Rust 要求你承认出错的可能性并在编译代码之前就采取行动。通过确保不会只有在将代码部署到生产环境之后才会发现错误来使得程序更可靠。 +Rust 对可靠性的执着也扩展到了错误处理。错误对于软件来说是不可避免的,所以当出现错误时, Rust 有很多特性来处理当前情况。在很多情况下,Rust 要求你承认出错的可能性并在编译代码之前就采取行动。通过确保不会只有在将代码部署到生产环境之后才会发现错误来使得程序更可靠。 Rust 将错误组合成两个主要类别:**可恢复错误**(*recoverable*)和 **不可恢复错误**(*unrecoverable*)。可恢复错误通常代表向用户报告错误和重试操作是合理的情况,比如未找到文件。不可恢复错误通常是 bug 的同义词,比如尝试访问超过数组结尾的位置。 From 51e5b7f6b428db1156c99a9cfe12c610fa422128 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Sun, 3 Dec 2017 12:57:14 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E6=8C=89=E7=85=A7=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E7=9A=84=E8=A7=84=E8=8C=83=EF=BC=8C=E6=AD=A4=E5=A4=84=E5=B0=91?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch11-01-writing-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch11-01-writing-tests.md b/src/ch11-01-writing-tests.md index a2d3b65..7aaf8fa 100644 --- a/src/ch11-01-writing-tests.md +++ b/src/ch11-01-writing-tests.md @@ -340,7 +340,7 @@ test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured 注意在一些语言和测试框架中,断言两个值相等的函数的参数叫做 `expected` 和 `actual`,而且指定参数的顺序是需要注意的。然而在 Rust 中,他们则叫做 `left` 和 `right`,同时指定期望的值和被测试代码产生的值的顺序并不重要。这个测试中的断言也可以写成 `assert_eq!(add_two(2), 4)`,这时错误信息会变成 `` assertion failed: `(left == right)` (left: `5`, right: `4`) ``。 -`assert_ne!` 宏在传递给它的两个值不相等时通过而在相等时失败。这个宏在代码按照我们期望运行时不确定值 **会** 是什么,不过知道他们绝对 **不会**是什么的时候最有用处。例如,如果一个函数确定会以某种方式改变其输出,不过这种方式由运行测试是星期几来决定,这时最好的断言可能就是函数的输出不等于其输入。 +`assert_ne!` 宏在传递给它的两个值不相等时通过而在相等时失败。这个宏在代码按照我们期望运行时不确定值 **会** 是什么,不过知道他们绝对 **不会** 是什么的时候最有用处。例如,如果一个函数确定会以某种方式改变其输出,不过这种方式由运行测试是星期几来决定,这时最好的断言可能就是函数的输出不等于其输入。 `assert_eq!` 和 `assert_ne!` 宏在底层分别使用了 `==` 和 `!=`。当断言失败时,这些宏会使用调试格式打印出其参数,这意味着被比较的值必需实现了 `PartialEq` 和 `Debug` trait。所有的基本类型和大部分标准库类型都实现了这些 trait。对于自定义的结构体和枚举,需要实现 `PartialEq` 才能断言他们的值是否相等。需要实现 `Debug` 才能在断言失败时打印他们的值。因为这两个 trait 都是可推导 trait,如第五章所提到的,通常可以直接在结构体或枚举上添加 `#[derive(PartialEq, Debug)]` 注解。附录 C 中有更多关于这些和其他可推导 trait 的详细信息。 From 804bb929cdb285207047a3b2c1e477617c8e6024 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Thu, 7 Dec 2017 19:45:50 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E4=B9=8B=E5=89=8D=E7=9A=84greprs?= =?UTF-8?q?=E5=B7=B2=E7=BB=8F=E6=9B=B4=E6=96=B0=E4=B8=BAminigrep=EF=BC=8C?= =?UTF-8?q?=E6=AD=A4=E4=B8=A4=E5=A4=84=E6=9C=AA=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch12-03-improving-error-handling-and-modularity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 3bd7722..28f8b94 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -416,7 +416,7 @@ pub fn run(config: Config) -> Result<(), Box> { 这里使用了公有的 `pub`:在 `Config`、其字段和其 `new`方法,以及 `run` 函数上。现在我们有了一个拥有可以测试的公有 API 的库 crate 了。 -现在需要在 *src/main.rs* 中使用 `extern crate greprs` 将移动到 *src/lib.rs* 的代码引入二进制 crate 的作用域。接着我们将增加一个 `use greprs::Config` 行将 `Config` 类型引入作用域,并使用库 crate 的名称作为 `run` 函数的前缀,如示例 12-14 所示: +现在需要在 *src/main.rs* 中使用 `extern crate minigrep` 将移动到 *src/lib.rs* 的代码引入二进制 crate 的作用域。接着我们将增加一个 `use minigrep::Config` 行将 `Config` 类型引入作用域,并使用库 crate 的名称作为 `run` 函数的前缀,如示例 12-14 所示: Filename: src/main.rs From 82e630c8235db5c5408076988ab0b214bedd67d4 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Sat, 9 Dec 2017 20:44:01 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch13-00-functional-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch13-00-functional-features.md b/src/ch13-00-functional-features.md index f902586..e7b91b3 100644 --- a/src/ch13-00-functional-features.md +++ b/src/ch13-00-functional-features.md @@ -4,7 +4,7 @@ >
> commit d06a6a181fd61704cbf7feb55bc61d518c6469f9 -Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是 **函数式编程**(*functional programming*)。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。我们不会在这里讨论函数式编程是或不是什么的问题,而是展示Rust的一些特性,这些特性与许多语言中被称为功能的特性类似。 +Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是 **函数式编程**(*functional programming*)。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。我们不会在这里讨论函数式编程是或不是什么的问题,而是展示Rust的一些在功能上与其他语言类似的特性。 更具体的,我们将要涉及: From bffafd193cf103ee9b597b8213929a23b614c4f1 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Mon, 11 Dec 2017 23:23:48 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=BF=BB=E8=AF=91?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch13-01-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index 505e369..446da6b 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -141,7 +141,7 @@ fn generate_workout(intensity: i32, random_number: i32) { 示例 13-4:将 `simulated_expensive_calculation` 调用提取到一个位置,位于 `if` 块之前并将结果储存在变量 `expensive_result` 中 -这个修改统一了 `simulated_expensive_calculation` 调用并解决了第一个 `if` 块中不必要的两次调用函数的问题。不幸的是,现在所有的情况下都需要调用函数并等待结果,而内部 `if` 块完全不需要其结果。 +这个修改统一了 `simulated_expensive_calculation` 调用并解决了第一个 `if` 块中不必要的两次调用函数的问题。不幸的是,现在所有的情况下都需要调用函数并等待结果,包括那个完全不需要这一结果的内部 `if` 块。 我们希望能够在程序的一个位置指定某些代码,并只在程序的某处实际需要结果的时候执行这些代码。这正是闭包的用武之地! From 580af26ad9837c145d1958d9d12bab6ef01de838 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Tue, 12 Dec 2017 01:03:14 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E5=88=AB?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch13-01-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index 446da6b..73c3661 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -304,7 +304,7 @@ struct Cacher 示例 13-9:定义一个 `Cacher` 结构体来在 `calculation` 中存放闭包并在 `value` 中存放 Option 值 -结果提 `Cacher` 有一个泛型 `T` 的字段 `calculation`。`T` 的 trait bound 指定了 `T` 是一个使用 `Fn` 的闭包。任何我们希望储存到 `Cacher` 实例的 `calculation` 字段的闭包必须有一个 `i32` 参数(由 `Fn` 之后的括号的内容指定)并必须返回一个 `i32`(由 `->` 之后的内容)。 +结构体 `Cacher` 有一个泛型 `T` 的字段 `calculation`。`T` 的 trait bound 指定了 `T` 是一个使用 `Fn` 的闭包。任何我们希望储存到 `Cacher` 实例的 `calculation` 字段的闭包必须有一个 `i32` 参数(由 `Fn` 之后的括号的内容指定)并必须返回一个 `i32`(由 `->` 之后的内容)。 `value` 是 `Option` 类型的。在执行闭包之前,`value` 将是 `None`。如果使用 `Cacher` 的代码请求闭包的结果,这时会执行闭包并将结果储存在 `value` 字段的 `Some` 成员中。接着如果代码再次请求闭包的结果,这时不再执行闭包,而是会返回存放在 `Some` 成员中的结果。 From a30686067092397c2f2a06e83fef393f90e85958 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Tue, 12 Dec 2017 01:08:15 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E5=88=AB?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ch13-01-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index 73c3661..c9812f1 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -308,7 +308,7 @@ struct Cacher `value` 是 `Option` 类型的。在执行闭包之前,`value` 将是 `None`。如果使用 `Cacher` 的代码请求闭包的结果,这时会执行闭包并将结果储存在 `value` 字段的 `Some` 成员中。接着如果代码再次请求闭包的结果,这时不再执行闭包,而是会返回存放在 `Some` 成员中的结果。 -刚才讨论的油管 `value` 字段逻辑定义于示例 13-10: +刚才讨论的有关 `value` 字段逻辑定义于示例 13-10: 文件名: src/main.rs From 00339cadcf36b83e52e2ae247fd26fc85ab166db Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Tue, 12 Dec 2017 23:56:50 +0800 Subject: [PATCH 13/13] fix mistakes --- src/ch07-01-mod-and-the-filesystem.md | 4 ---- src/ch09-00-error-handling.md | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/ch07-01-mod-and-the-filesystem.md b/src/ch07-01-mod-and-the-filesystem.md index 5194adf..902a74b 100644 --- a/src/ch07-01-mod-and-the-filesystem.md +++ b/src/ch07-01-mod-and-the-filesystem.md @@ -31,11 +31,7 @@ Cargo 创建了一个空的测试来帮助我们开始库项目,不像使用 ` 因为没有 *src/main.rs* 文件,所以没有可供 Cargo 的 `cargo run` 执行的东西。因此,我们将使用 `cargo build` 命令只是编译库 crate 的代码。 -<<<<<<< HEAD -我们将学习根据编写代码的意图来选择不同的库项目代码组织来适应多种场景。 -======= 我们将学习根据编写代码的意图来以不同方法组织库项目代码以适应多种情况。 ->>>>>>> 828c1412827d09b3a539566ec64e2560fd5fd22d ### 模块定义 diff --git a/src/ch09-00-error-handling.md b/src/ch09-00-error-handling.md index 0a590a3..609d6ee 100644 --- a/src/ch09-00-error-handling.md +++ b/src/ch09-00-error-handling.md @@ -4,11 +4,7 @@ >
> commit 4f2dc564851dc04b271a2260c834643dfd86c724 -<<<<<<< HEAD -Rust 对可靠性的执着也扩展到了错误处理。错误对于软件来说是不可避免的,所以 Rust 有很多功能来处理出现错误的情况。在很多情况下,Rust 要求你承认出错的可能性并在编译代码之前就采取行动。通过确保不会只有在将代码部署到生产环境之后才会发现错误来使得程序更可靠。 -======= Rust 对可靠性的执着也扩展到了错误处理。错误对于软件来说是不可避免的,所以当出现错误时, Rust 有很多特性来处理当前情况。在很多情况下,Rust 要求你承认出错的可能性并在编译代码之前就采取行动。通过确保不会只有在将代码部署到生产环境之后才会发现错误来使得程序更可靠。 ->>>>>>> 828c1412827d09b3a539566ec64e2560fd5fd22d Rust 将错误组合成两个主要类别:**可恢复错误**(*recoverable*)和 **不可恢复错误**(*unrecoverable*)。可恢复错误通常代表向用户报告错误和重试操作是合理的情况,比如未找到文件。不可恢复错误通常是 bug 的同义词,比如尝试访问超过数组结尾的位置。