From 659c6cf5563923a8500744f40304f3725994ec72 Mon Sep 17 00:00:00 2001 From: Xmasreturns Date: Tue, 3 May 2016 17:27:38 -0700 Subject: [PATCH] Updated and restructured Ch16.5, 16.6 Readability and grammar changes Renamed "Result as an alias" to "aliases for Result" Made "map for Result" and "aliases for Result" into children of "Result" --- examples/error/result/result_alias/alias.rs | 23 ++++++++++++++++++ examples/error/result/result_alias/input.md | 18 ++++++++++++++ examples/error/result/result_map/input.md | 24 +++++++++++++++++++ .../error/{ => result}/result_map/result.rs | 12 +++++----- examples/error/result_alias/alias.rs | 23 ------------------ examples/error/result_alias/input.md | 16 ------------- examples/error/result_map/input.md | 21 ---------------- examples/structure.json | 7 +++--- 8 files changed, 75 insertions(+), 69 deletions(-) create mode 100644 examples/error/result/result_alias/alias.rs create mode 100644 examples/error/result/result_alias/input.md create mode 100644 examples/error/result/result_map/input.md rename examples/error/{ => result}/result_map/result.rs (66%) delete mode 100644 examples/error/result_alias/alias.rs delete mode 100644 examples/error/result_alias/input.md delete mode 100644 examples/error/result_map/input.md diff --git a/examples/error/result/result_alias/alias.rs b/examples/error/result/result_alias/alias.rs new file mode 100644 index 0000000000..e3113ac3fe --- /dev/null +++ b/examples/error/result/result_alias/alias.rs @@ -0,0 +1,23 @@ +use std::num::ParseIntError; +use std::result; + +// Define a generic alias for a `Result` of type `ParseIntError`. +type AliasedResult = result::Result; + +// Use the alias defined above to refer to our specific `Result` type. +fn double_number(number_str: &str) -> AliasedResult { + number_str.parse::().map(|n| 2 * n) +} + +// Here, the alias again allows us to save some space. +fn print(result: AliasedResult) { + match result { + Ok(n) => println!("n is {}", n), + Err(e) => println!("Error: {}", e), + } +} + +fn main() { + print(double_number("10")); + print(double_number("t")); +} diff --git a/examples/error/result/result_alias/input.md b/examples/error/result/result_alias/input.md new file mode 100644 index 0000000000..2f8175737c --- /dev/null +++ b/examples/error/result/result_alias/input.md @@ -0,0 +1,18 @@ +How about when we want to reuse a specific `Result` type many times? +It quickly becomes tedious to write out the full type name, but recall that Rust allows +us to create [aliases][alias]. A generic alias may conveniently be defined for the +specific `Result` in question: + +{alias.play} + +At a module level, creating aliases can be particularly helpful. Errors +found in a specific module often have the same `Err` type, so a single alias can succinctly +define *all* associated `Results`. This is so useful that the `std` library even supplies one: `io::Result`! + +### See also: + +[`Result`][result] and [`io::Result`][io_result] + +[alias]: /cast/alias.html +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result/result_map/input.md b/examples/error/result/result_map/input.md new file mode 100644 index 0000000000..00641072a5 --- /dev/null +++ b/examples/error/result/result_map/input.md @@ -0,0 +1,24 @@ +Panicking on `unwrap()` in the previous example gave us an unhelpful error message. +To avoid that, we need to be more specific about the return type. In that example, +recall that the regular element is of type `i32`. To determine the `Err` type, we +look to `parse()`. `parse()` is implemented with the [`FromStr trait`][from_str] +for [`i32`][i32]. As a result, the `Err` type is specified as [`ParseIntError`][parse_int_error]. + +In the example below, note that using the straightforward `match` statement leads to +more cumbersome code. As it turns out, the `map` method we used with `Option` +is also implemented for `Result`. + +{result.play} + +Much like `Option`, `Result` implements combinators besides `map`, such as `and_then` +and `unwrap_or`. This even includes those that specifically handle errors, like `map_err`. +[`Result`][result] contains the complete listing. + +### See also: + +[`i32`][i32], [`FromStr`][from_str], and [`ParseIntErr`][parse_int_error] + +[result]: http://doc.rust-lang.org/std/result/enum.Result.html +[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html +[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html +[i32]: http://doc.rust-lang.org/std/primitive.i32.html diff --git a/examples/error/result_map/result.rs b/examples/error/result/result_map/result.rs similarity index 66% rename from examples/error/result_map/result.rs rename to examples/error/result/result_map/result.rs index 6f7a741837..bb009b24c2 100644 --- a/examples/error/result_map/result.rs +++ b/examples/error/result/result_map/result.rs @@ -1,8 +1,7 @@ use std::num::ParseIntError; // With the return type rewritten, we proceed to use pattern matching without -// `unwrap()` but it is tedious. Couldn't a combinator like in the `Option` -// example also be used here? Yes. +// `unwrap()`, but it is tedious. fn double_number(number_str: &str) -> Result { match number_str.parse::() { Ok(n) => Ok(2 * n), @@ -10,8 +9,9 @@ fn double_number(number_str: &str) -> Result { } } -// The exact same but written with `map()`. Modify if the value is valid, -// otherwise pass the error on. +// As with `Option`, we can use combinators such as `map()`. +// This function is otherwise identical to the one above and reads: +// Modify n if the value is valid, otherwise pass on the error. fn double_number_map(number_str: &str) -> Result { number_str.parse::().map(|n| 2 * n) } @@ -24,11 +24,11 @@ fn print(result: Result) { } fn main() { - // Still presents a reasonable answer. + // This still presents a reasonable answer. let twenty = double_number("10"); print(twenty); - // This is now much better than before with the messy `panic`. + // The following now provides a much more useful error message let tt = double_number_map("t"); print(tt); } diff --git a/examples/error/result_alias/alias.rs b/examples/error/result_alias/alias.rs deleted file mode 100644 index dd9a8ade10..0000000000 --- a/examples/error/result_alias/alias.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::num::ParseIntError; -use std::result; - -// A generic alias for any `Result` with this specific `Err` type. -type Result = result::Result; - -// Use the alias defined above referring to our specific `Result` type. -fn double_number(number_str: &str) -> Result { - number_str.parse::().map(|n| 2 * n) -} - -// Again, the alias saved us from defining it again. -fn print(result: Result) { - match result { - Ok(n) => println!("n is {}", n), - Err(e) => println!("Error: {}", e), - } -} - -fn main() { - print(double_number("10")); - print(double_number("t")); -} diff --git a/examples/error/result_alias/input.md b/examples/error/result_alias/input.md deleted file mode 100644 index cb4657b974..0000000000 --- a/examples/error/result_alias/input.md +++ /dev/null @@ -1,16 +0,0 @@ -What if the specific `Result` type is reused many many times? Then quickly it becomes tedious -to write out the full type name. Instead, a generic alias for the specific `Result` may be -defined. - -{alias.play} - -This is particularly helpful at a module level because all errors found in a specific module -may have the same `Err` type; a single alias succinctly defines *all* module `Results`. This -is so useful that the std library even supplies one: `io::Result` which refers to IO errors. - -### See also: - -[`Result`][result] and [`io::Result`][io_result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[io_result]: http://doc.rust-lang.org/std/io/type.Result.html diff --git a/examples/error/result_map/input.md b/examples/error/result_map/input.md deleted file mode 100644 index 6af4fcbc89..0000000000 --- a/examples/error/result_map/input.md +++ /dev/null @@ -1,21 +0,0 @@ -To avoid the `unwrap()` in the previous example, we will have to rewrite the example to be -specific about what type it returns. In this case, the regular element should definitely -be `i32` but what about the `Err` type? Well, `parse()` is implemented with the -[`FromStr trait`][from_str] for [`i32`][i32]. That implementation specifies the -`Err` type as [`ParseIntError`][parse_int_error]. - -{result.play} - -Similar to `Option`, `Result` has many other combinators besides `map` such as `and_then` -and `unwrap_or`; even ones to handle the errors specifically such as `map_err`. -`Result` contains the complete listing. - -### See also: - -[`i32`][i32], [`FromStr`][from_str], [`ParseIntErr`][parse_int_error], and -[`Result`][result] - -[result]: http://doc.rust-lang.org/std/result/enum.Result.html -[parse_int_error]: http://doc.rust-lang.org/std/num/struct.ParseIntError.html -[from_str]: http://doc.rust-lang.org/std/str/trait.FromStr.html -[i32]: http://doc.rust-lang.org/std/primitive.i32.html diff --git a/examples/structure.json b/examples/structure.json index 6364343951..00ac357d9b 100644 --- a/examples/structure.json +++ b/examples/structure.json @@ -143,9 +143,10 @@ { "id": "unwrap", "title": "Option & unwrap", "children": null }, { "id": "map", "title": "map", "children": null }, { "id": "and_then", "title": "and_then", "children": null }, - { "id": "result", "title": "Result", "children": null }, - { "id": "result_map", "title": "map for Result", "children": null }, - { "id": "result_alias", "title": "Result as an alias", "children": null }, + { "id": "result", "title": "Result", "children": [ + { "id": "result_map", "title": "map for Result", "children": null }, + { "id": "result_alias", "title": "aliases for Result", "children": null }, + ] }, { "id": "option_with_result", "title": "Options with Results", "children": [ { "id": "result_string_errors", "title": "Errors as strings", "children": null }, { "id": "combinator_combinations", "title": "Combining separate combinators", "children": null },