From 01627a9637f9faf3a4983f211521ca5871727b0e Mon Sep 17 00:00:00 2001 From: mg-chao Date: Sun, 16 Jan 2022 12:13:59 +0800 Subject: [PATCH] update: translate errors --- exercise/exercises/error_handling/README.md | 11 +-- exercise/exercises/error_handling/errors1.rs | 25 +++---- exercise/exercises/error_handling/errors2.rs | 30 ++++---- exercise/exercises/error_handling/errors3.rs | 11 ++- exercise/exercises/error_handling/errors4.rs | 2 +- exercise/exercises/error_handling/errors5.rs | 12 +-- exercise/exercises/error_handling/errors6.rs | 22 +++--- exercise/info.toml | 77 ++++++++------------ 8 files changed, 83 insertions(+), 107 deletions(-) diff --git a/exercise/exercises/error_handling/README.md b/exercise/exercises/error_handling/README.md index 5255ace9..1c8be794 100644 --- a/exercise/exercises/error_handling/README.md +++ b/exercise/exercises/error_handling/README.md @@ -1,9 +1,10 @@ -# Error handling -Most errors aren’t serious enough to require the program to stop entirely. -Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to. -For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process. +# 错误处理 +大多数的错误并没有严重到需要让程序完全停止运行的程度。 +有时一个函数执行失败时,你可以很容易地对造成失败的原因进行解释并采取对应措施的。 +例如,你正试图打开一个文件,但由于该文件不存在导致了操作失败,这时你可能想创建 +该文件而不是直接终止程序。 -## Further information +## 更多信息 - [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html) - [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html) diff --git a/exercise/exercises/error_handling/errors1.rs b/exercise/exercises/error_handling/errors1.rs index 9c24d85d..6febd544 100644 --- a/exercise/exercises/error_handling/errors1.rs +++ b/exercise/exercises/error_handling/errors1.rs @@ -1,18 +1,16 @@ // errors1.rs -// This function refuses to generate text to be printed on a nametag if -// you pass it an empty string. It'd be nicer if it explained what the problem -// was, instead of just sometimes returning `None`. The 2nd test currently -// does not compile or pass, but it illustrates the behavior we would like -// this function to have. -// Execute `rustlings hint errors1` for hints! +// 假使你传给这个函数一个空字符串,那么它将拒绝生成一段个性签名(nametage)。 +// 如果它能解释拒绝的原因是什么,而不是粗暴返回 `None` 那就更完美了。 +// 第 2 个测试目前还没通过并未能编译,但它说明了我们希望这个函数具有的行为。 +// 执行 `rustlings hint errors1` 获取提示! // I AM NOT DONE -pub fn generate_nametag_text(name: String) -> Option { +pub fn generate_nametag_text(name: String) -> Option {// 译:生成个性签名 if name.len() > 0 { - Some(format!("Hi! My name is {}", name)) + Some(format!("Hi! My name is {}", name))// 译:"嗨!我的名字是 {}" } else { - // Empty names aren't allowed. + // 不允许使用空的名字。 None } } @@ -21,11 +19,10 @@ pub fn generate_nametag_text(name: String) -> Option { mod tests { use super::*; - // This test passes initially if you comment out the 2nd test. - // You'll need to update what this test expects when you change - // the function under test! + // 你可以注释掉第 2 个测试,那么这个测试就能初步通过。 + // 当你更改了测试的函数时,也需要修改下测试代码以使测试正确! #[test] - fn generates_nametag_text_for_a_nonempty_name() { + fn generates_nametag_text_for_a_nonempty_name() {// 译:用一个非空名称生成一段个性签名 assert_eq!( generate_nametag_text("Beyoncé".into()), Some("Hi! My name is Beyoncé".into()) @@ -33,7 +30,7 @@ mod tests { } #[test] - fn explains_why_generating_nametag_text_fails() { + fn explains_why_generating_nametag_text_fails() {// 译:说明为什么个性签名生成失败了 assert_eq!( generate_nametag_text("".into()), Err("`name` was empty; it must be nonempty.".into()) diff --git a/exercise/exercises/error_handling/errors2.rs b/exercise/exercises/error_handling/errors2.rs index aad3a93f..c7dacdcc 100644 --- a/exercise/exercises/error_handling/errors2.rs +++ b/exercise/exercises/error_handling/errors2.rs @@ -1,20 +1,16 @@ // errors2.rs -// Say we're writing a game where you can buy items with tokens. All items cost -// 5 tokens, and whenever you purchase items there is a processing fee of 1 -// token. A player of the game will type in how many items they want to buy, -// and the `total_cost` function will calculate the total number of tokens. -// Since the player typed in the quantity, though, we get it as a string-- and -// they might have typed anything, not just numbers! - -// Right now, this function isn't handling the error case at all (and isn't -// handling the success case properly either). What we want to do is: -// if we call the `parse` function on a string that is not a number, that -// function will return a `ParseIntError`, and in that case, we want to -// immediately return that error from our function and not try to multiply -// and add. - -// There are at least two ways to implement this that are both correct-- but -// one is a lot shorter! Execute `rustlings hint errors2` for hints to both ways. +// 假设我们正在编写一个游戏,你可以用代币购买物品。 +// 所有物品的价格都是 5 个代币,每当你购买物品时,都需要 1 个代币的小费。 +// 游戏玩家将输入他们想要购买的物品数量,`total_cost` 函数能够计算出所需的代币数量。 +// 虽然玩家输入的是数量,但我们得到的却是一个字符串——他们可能输入了任何东西,而不仅仅是数字! + +// 目前这个函数没有处理任何错误的情况(也没有处理成功的情况)。 +// 我们要做的是: +// 如果我们在非数字的字符串上调用 `parse` 方法,该方法将返回 `ParseIntError`, +// 在这种情况下,我们要立刻从函数返回这个错误,而不是继续进行相关计算。 + +// 至少有两种方法可以做到这点,它们都是正确的——但其中一种简短得多! +// 执行 `rustlings hint errors2` 以获得关于这两种方式的提示。 // I AM NOT DONE @@ -42,6 +38,6 @@ mod tests { assert_eq!( total_cost("beep boop").unwrap_err().to_string(), "invalid digit found in string" - ); + );// 译:字符串中包含无效的数字 } } diff --git a/exercise/exercises/error_handling/errors3.rs b/exercise/exercises/error_handling/errors3.rs index 460ac5c4..95afe76e 100644 --- a/exercise/exercises/error_handling/errors3.rs +++ b/exercise/exercises/error_handling/errors3.rs @@ -1,8 +1,7 @@ // errors3.rs -// This is a program that is trying to use a completed version of the -// `total_cost` function from the previous exercise. It's not working though! -// Why not? What should we do to fix it? -// Execute `rustlings hint errors3` for hints! +// 这是一个试图使用前面练习中 `total_cost` 函数完整版的程序。 +// 但出了些问题!为什么不行?我们需要怎样做才能解决问题? +// 执行 `rustlings hint errors3` 获取提示! // I AM NOT DONE @@ -15,10 +14,10 @@ fn main() { let cost = total_cost(pretend_user_input)?; if cost > tokens { - println!("You can't afford that many!"); + println!("You can't afford that many!");// 译:你的代币不足以完成支付! } else { tokens -= cost; - println!("You now have {} tokens.", tokens); + println!("You now have {} tokens.", tokens);// 译:现在你有 {} 个代币" } } diff --git a/exercise/exercises/error_handling/errors4.rs b/exercise/exercises/error_handling/errors4.rs index 0685c374..99b23023 100644 --- a/exercise/exercises/error_handling/errors4.rs +++ b/exercise/exercises/error_handling/errors4.rs @@ -1,5 +1,5 @@ // errors4.rs -// Make this test pass! Execute `rustlings hint errors4` for hints :) +// 通过测试!执行 `rustlings hint errors4` 获取提示 :) // I AM NOT DONE diff --git a/exercise/exercises/error_handling/errors5.rs b/exercise/exercises/error_handling/errors5.rs index 365a8691..e67ed82e 100644 --- a/exercise/exercises/error_handling/errors5.rs +++ b/exercise/exercises/error_handling/errors5.rs @@ -1,8 +1,8 @@ // errors5.rs -// This program uses a completed version of the code from errors4. -// It won't compile right now! Why? -// Execute `rustlings hint errors5` for hints! +// 这个程序使用练习 errors4 代码的完整版。 +// 它现在不能编译! 为什么呢? +// 执行 `rustlings hint errors5` 获取提示! // I AM NOT DONE @@ -10,7 +10,7 @@ use std::error; use std::fmt; use std::num::ParseIntError; -// TODO: update the return type of `main()` to make this compile. +// TODO:修改 `main()` 的返回类型,以使其通过编译。 fn main() -> Result<(), ParseIntError> { let pretend_user_input = "42"; let x: i64 = pretend_user_input.parse()?; @@ -18,7 +18,7 @@ fn main() -> Result<(), ParseIntError> { Ok(()) } -// Don't change anything below this line. +// 不要更改此行以下的任何内容。 #[derive(PartialEq, Debug)] struct PositiveNonzeroInteger(u64); @@ -39,7 +39,7 @@ impl PositiveNonzeroInteger { } } -// This is required so that `CreationError` can implement `error::Error`. +// 以下是必要的,以便 `CreationError` 能够实现 `error::Error` 。 impl fmt::Display for CreationError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let description = match *self { diff --git a/exercise/exercises/error_handling/errors6.rs b/exercise/exercises/error_handling/errors6.rs index 0f6b27a6..c631e074 100644 --- a/exercise/exercises/error_handling/errors6.rs +++ b/exercise/exercises/error_handling/errors6.rs @@ -1,18 +1,17 @@ // errors6.rs -// Using catch-all error types like `Box` isn't recommended -// for library code, where callers might want to make decisions based on the -// error content, instead of printing it out or propagating it further. Here, -// we define a custom error type to make it possible for callers to decide -// what to do next when our function returns an error. +// 像 `Box` 这样的万能错误类型并不推荐用于库代码, +// 因为调用者可能想根据错误内容进行相关处理,而不是将其打印出来或进一步传播。 +// 在这里,我们自定义了一个错误类型,让调用者有可能去决定当函数返回错误时 +// 下一步该怎么做 -// Make these tests pass! Execute `rustlings hint errors6` for hints :) +// 通过这些测试!执行 `rustlings hint errors6` 获取提示 :) // I AM NOT DONE use std::num::ParseIntError; -// This is a custom error type that we will be using in `parse_pos_nonzero()`. +// 这是一个自定义的错误类型,我们将在 `parse_pos_nonzero()` 中使用。 #[derive(PartialEq, Debug)] enum ParsePosNonzeroError { Creation(CreationError), @@ -23,20 +22,19 @@ impl ParsePosNonzeroError { fn from_creation(err: CreationError) -> ParsePosNonzeroError { ParsePosNonzeroError::Creation(err) } - // TODO: add another error conversion function here. + // TODO:在这添加另一个错误转换函数。 } fn parse_pos_nonzero(s: &str) -> Result { - // TODO: change this to return an appropriate error instead of panicking - // when `parse()` returns an error. + // TODO:改为返回一个恰当的错误,而不是在 `parse()` 返回一个错误时 panic let x: i64 = s.parse().unwrap(); PositiveNonzeroInteger::new(x) .map_err(ParsePosNonzeroError::from_creation) } -// Don't change anything below this line. +// 不要更改这一行以下的任何内容。 #[derive(PartialEq, Debug)] struct PositiveNonzeroInteger(u64); @@ -63,7 +61,7 @@ mod test { #[test] fn test_parse_error() { - // We can't construct a ParseIntError, so we have to pattern match. + // 我们不能构造一个 ParseIntError ,所以必须进行模式匹配。 assert!(matches!( parse_pos_nonzero("not a number"), Err(ParsePosNonzeroError::ParseInt(_)) diff --git a/exercise/info.toml b/exercise/info.toml index 05d3bc33..ac72b999 100644 --- a/exercise/info.toml +++ b/exercise/info.toml @@ -433,74 +433,63 @@ name = "errors1" path = "exercises/error_handling/errors1.rs" mode = "test" hint = """ -`Err` is one of the variants of `Result`, so what the 2nd test is saying -is that `generate_nametag_text` should return a `Result` instead of an -`Option`. +`Err` 是 `Result` 的成员之一,所以第二个测试的意思是 `generate_nametag_text` +应该返回 `Result` 而不是 `Option` 。 -To make this change, you'll need to: - - update the return type in the function signature to be a Result that - could be the variants `Ok(String)` and `Err(String)` - - change the body of the function to return `Ok(stuff)` where it currently - returns `Some(stuff)` - - change the body of the function to return `Err(error message)` where it - currently returns `None` - - change the first test to expect `Ok(stuff)` where it currently expects - `Some(stuff)`.""" +要做到这些改变,你需要: + - 修改函数签名的返回类型为 Result,以便能返回 `Ok(String)` 和 `Err(String)`。 + - 更改函数返回值 `Some(stuff)` 为 `Ok(stuff)` 。 + - 更改函数返回值 `None` 为 `Err(error message)` 。 + - 将第一个测试预期的值从 `Some(stuff)` 改为 `Ok(stuff)`。""" [[exercises]] name = "errors2" path = "exercises/error_handling/errors2.rs" mode = "test" hint = """ -One way to handle this is using a `match` statement on -`item_quantity.parse::()` where the cases are `Ok(something)` and -`Err(something)`. This pattern is very common in Rust, though, so there's -a `?` operator that does pretty much what you would make that match statement -do for you! Take a look at this section of the Error Handling chapter: +解决这个问题的一个方法是对 `item_quantity.parse::()` 使用 match 语句, +其中有两种情况需要被处理,分别是 `Ok(something)` 和 `Err(something)`。 +不过这种方法在 Rust 中很常见,所以有一个 `?` 操作符,作用几乎符合你想让匹配语句做的事! +看一下 Error Handling 章节的这部分: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator -and give it a try!""" +然后试一试!""" [[exercises]] name = "errors3" path = "exercises/error_handling/errors3.rs" mode = "compile" hint = """ -If other functions can return a `Result`, why shouldn't `main`?""" +如果其它函数可以返回 `Result`,为什么 `main` 函数不能?""" [[exercises]] name = "errors4" path = "exercises/error_handling/errors4.rs" mode = "test" hint = """ -`PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result. -It should be doing some checking, returning an `Err` result if those checks fail, and only -returning an `Ok` result if those checks determine that everything is... okay :)""" +`PositiveNonzeroInteger::new` 将创建一个新的实例,并返回一个 `Ok` 。 +它应该做一些检查,如果检查到失败,则返回 `Err` ,如果确定一切正常,则返回 `Ok` :)。""" [[exercises]] name = "errors5" path = "exercises/error_handling/errors5.rs" mode = "compile" hint = """ -Hint: There are two different possible `Result` types produced within -`main()`, which are propagated using `?` operators. How do we declare a -return type from `main()` that allows both? +提示:在 `main()` 中产生了两种 `Result` 类型,它们是通过 `?` 运算符返回的。 +那么我们如何在 `main()` 中声明一个容纳这两者的返回类型? -Another hint: under the hood, the `?` operator calls `From::from` -on the error value to convert it to a boxed trait object, a -`Box`, which is polymorphic-- that means that lots of -different kinds of errors can be returned from the same function because -all errors act the same since they all implement the `error::Error` trait. -Check out this section of the book: +额外提示:`?` 操作符的底层实现实际上是对错误值调用了 `From::from` ,将其转换为 +了 `Box` 类型。它是多态的——这意味着不同类型的错误可以从同一个函数返回, +因为它们都实现了`error::Error`特征,行为都是一致的。 +请看这本书的这一部分: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator -This exercise uses some concepts that we won't get to until later in the -course, like `Box` and the `From` trait. It's not important to understand -them in detail right now, but you can read ahead if you like. +这个练习使用了一些课程后期才会介绍到的概念,如 `Box` 指针和 `From` 特征。 +现在详细了解它们并不重要,但如果你感兴趣,可以提前阅读。 -Read more about boxing errors: +阅读更多装箱错误(boxing errors)的内容: https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html -Read more about using the `?` operator with boxed errors: +阅读更多关于使用 `?` 操作符和装箱错误的内容。 https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html """ @@ -509,19 +498,15 @@ name = "errors6" path = "exercises/error_handling/errors6.rs" mode = "test" hint = """ -This exercise uses a completed version of `PositiveNonzeroInteger` from -errors4. +这个练习使用的是来自于 error 4 的 `PositiveNonzeroInteger` 完整版本。 -Below the line that TODO asks you to change, there is an example of using -the `map_err()` method on a `Result` to transform one type of error into -another. Try using something similar on the `Result` from `parse()`. You -might use the `?` operator to return early from the function, or you might -use a `match` expression, or maybe there's another way! +在 TODO 要求你修改的那一行下面,有一个在 `Result` 上使用 `map_err()` 方法将 +一种类型的错误转换为另一种类型的例子。尝试在 `parse()` 的 `Result` 上使用类似的东西。 +你可能使用 `?` 操作符在函数中提前返回,或者使用 `match` 表达式,以及等等其它方法。 -You can create another function inside `impl ParsePosNonzeroError` to use -with `map_err()`. +你可以在 `impl ParsePosNonzeroError` 内创建另一个方法来配合 `map_err()` 使用。 -Read more about `map_err()` in the `std::result` documentation: +在 `std::result` 文档了解更多关于 `map_err()` 的信息: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err""" # Generics