From 76e3bc23388e268438e4318b0580149619a9d1ac Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 23 Dec 2014 13:31:43 -0500 Subject: [PATCH] Properly deal with Ordering in the guide Now that it's been removed from the prelude, we need to treat things differently. Fixes #17967 --- src/doc/guide.md | 82 ++++++++++++++++++------------- src/libstd/sys/windows/process.rs | 1 + src/test/run-pass/bool.rs | 2 +- src/test/run-pass/tcp-stress.rs | 11 +++-- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index e90f30cb864..a3a24abeb2e 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1106,10 +1106,17 @@ enum Ordering { ``` An `Ordering` can only be _one_ of `Less`, `Equal`, or `Greater` at any given -time. Here's an example: +time. + +Because `Ordering` is provided by the standard library, we can use the `use` +keyword to use it in our code. We'll learn more about `use` later, but it's +used to bring names into scope. + +Here's an example of how to use `Ordering`: ```{rust} -# use std::cmp::Ordering; +use std::cmp::Ordering; + fn cmp(a: int, b: int) -> Ordering { if a < b { Ordering::Less } else if a > b { Ordering::Greater } @@ -1132,18 +1139,25 @@ fn main() { } ``` -`cmp` is a function that compares two things, and returns an `Ordering`. We -return either `Less`, `Greater`, or `Equal`, depending on if the two values -are greater, less, or equal. +There's a symbol here we haven't seen before: the double colon (`::`). +This is used to indicate a namesapce. In this case, `Ordering` lives in +the `cmp` submodule of the `std` module. We'll talk more about modules +later in the guide. For now, all you need to know is that you can `use` +things from the standard library if you need them. -The `ordering` variable has the type `Ordering`, and so contains one of the -three values. We can then do a bunch of `if`/`else` comparisons to check -which one it is. +Okay, let's talk about the actual code in the example. `cmp` is a function that +compares two things, and returns an `Ordering`. We return either +`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if +the two values are greater, less, or equal. Note that each variant of the +`enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not +`Greater`. -However, repeated `if`/`else` comparisons get quite tedious. Rust has a feature -that not only makes them nicer to read, but also makes sure that you never -miss a case. Before we get to that, though, let's talk about another kind of -enum: one with values. +The `ordering` variable has the type `Ordering`, and so contains one of the +three values. We can then do a bunch of `if`/`else` comparisons to check which +one it is. However, repeated `if`/`else` comparisons get quite tedious. Rust +has a feature that not only makes them nicer to read, but also makes sure that +you never miss a case. Before we get to that, though, let's talk about another +kind of enum: one with values. This enum has two variants, one of which has a value: @@ -1176,18 +1190,19 @@ enum StringResult { ErrorReason(String), } ``` -Where a `StringResult` is either a `StringOK`, with the result of a computation, or an -`ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of -`enum`s are actually very useful and are even part of the standard library. +Where a `StringResult` is either a `StringResult::StringOK`, with the result of +a computation, or an `StringResult::ErrorReason` with a `String` explaining +what caused the computation to fail. These kinds of `enum`s are actually very +useful and are even part of the standard library. -Enum variants are namespaced under the enum names. For example, here is an example of using -our `StringResult`: +Here is an example of using our `StringResult`: ```rust -# enum StringResult { -# StringOK(String), -# ErrorReason(String), -# } +enum StringResult { + StringOK(String), + ErrorReason(String), +} + fn respond(greeting: &str) -> StringResult { if greeting == "Hello" { StringResult::StringOK("Good morning!".to_string()) @@ -1197,10 +1212,7 @@ fn respond(greeting: &str) -> StringResult { } ``` -Notice that we need both the enum name and the variant name: `StringResult::StringOK`, but -we didn't need to with `Ordering` – we just said `Greater` rather than `Ordering::Greater`. -There's a reason: the Rust prelude imports the variants of `Ordering` as well as the enum -itself. We can use the `use` keyword to do something similar with `StringResult`: +That's a lot of typing! We can use the `use` keyword to make it shorter: ```rust use StringResult::StringOK; @@ -1222,12 +1234,11 @@ fn respond(greeting: &str) -> StringResult { } ``` -We'll learn more about `use` later, but it's used to bring names into scope. `use` declarations -must come before anything else, which looks a little strange in this example, since we `use` -the variants before we define them. Anyway, in the body of `respond`, we can just say `StringOK` -now, rather than the full `StringResult::StringOK`. Importing variants can be convenient, but can -also cause name conflicts, so do this with caution. It's considered good style to rarely import -variants for this reason. +`use` declarations must come before anything else, which looks a little strange in this example, +since we `use` the variants before we define them. Anyway, in the body of `respond`, we can just +say `StringOK` now, rather than the full `StringResult::StringOK`. Importing variants can be +convenient, but can also cause name conflicts, so do this with caution. It's considered good style +to rarely import variants for this reason. As you can see, `enum`s with values are quite a powerful tool for data representation, and can be even more useful when they're generic across types. Before we get to generics, @@ -1281,7 +1292,8 @@ for every possible value of `x`, and so our program will compile successfully. section on enums? ```{rust} -# use std::cmp::Ordering; +use std::cmp::Ordering; + fn cmp(a: int, b: int) -> Ordering { if a < b { Ordering::Less } else if a > b { Ordering::Greater } @@ -1307,7 +1319,8 @@ fn main() { We can re-write this as a `match`: ```{rust} -# use std::cmp::Ordering; +use std::cmp::Ordering; + fn cmp(a: int, b: int) -> Ordering { if a < b { Ordering::Less } else if a > b { Ordering::Greater } @@ -1368,7 +1381,8 @@ side of a `let` binding or directly where an expression is used. We could also implement the previous line like this: ```{rust} -# use std::cmp::Ordering; +use std::cmp::Ordering; + fn cmp(a: int, b: int) -> Ordering { if a < b { Ordering::Less } else if a > b { Ordering::Greater } diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 00c1ca7fe1a..cb99a886ce4 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -467,6 +467,7 @@ fn free_handle(handle: *mut ()) { #[cfg(test)] mod tests { + use c_str::ToCStr; #[test] fn test_make_command_line() { diff --git a/src/test/run-pass/bool.rs b/src/test/run-pass/bool.rs index 45710408172..b3c4802530e 100644 --- a/src/test/run-pass/bool.rs +++ b/src/test/run-pass/bool.rs @@ -10,7 +10,7 @@ // Basic boolean tests -use std::cmp::{Equal, Greater, Less}; +use std::cmp::Ordering::{Equal, Greater, Less}; use std::ops::{BitAnd, BitOr, BitXor}; fn main() { diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index b3391669d35..7a061f5b99c 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -17,22 +17,23 @@ extern crate log; extern crate libc; +use std::comm::channel; use std::io::net::tcp::{TcpListener, TcpStream}; use std::io::{Acceptor, Listener}; -use std::thread::Builder; +use std::thread::{Builder, Thread}; use std::time::Duration; fn main() { // This test has a chance to time out, try to not let it time out - spawn(move|| { + Thread::spawn(move|| -> () { use std::io::timer; timer::sleep(Duration::milliseconds(30 * 1000)); println!("timed out!"); unsafe { libc::exit(1) } - }); + }).detach(); let (tx, rx) = channel(); - spawn(move|| { + Thread::spawn(move || -> () { let mut listener = TcpListener::bind("127.0.0.1:0").unwrap(); tx.send(listener.socket_name().unwrap()); let mut acceptor = listener.listen(); @@ -47,7 +48,7 @@ fn main() { stream.read_byte(); stream.write(&[2]); } - }); + }).detach(); let addr = rx.recv(); let (tx, rx) = channel(); -- GitLab