Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluate # fn in docs #21050

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 47 additions & 35 deletions src/doc/trpl/threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ closure is limited to capturing `Send`-able data from its environment
ensures that `spawn` can safely move the entire closure and all its
associated state into an entirely different thread for execution.

```{rust,ignore}
# use std::thread::spawn;
# fn generate_thread_number() -> int { 0 }
```rust
use std::thread::Thread;

fn generate_thread_number() -> i32 { 4 } // a very simple generation

// Generate some state locally
let child_thread_number = generate_thread_number();

spawn(move || {
Thread::spawn(move || {
// Capture it in the remote thread. The `move` keyword indicates
// that this closure should move `child_thread_number` into its
// environment, rather than capturing a reference into the
Expand All @@ -77,40 +79,44 @@ The simplest way to create a channel is to use the `channel` function to create
of a channel, and a *receiver* is the receiving endpoint. Consider the following
example of calculating two results concurrently:

```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;

let (tx, rx): (Sender<int>, Receiver<int>) = channel();
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();

spawn(move || {
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});

some_other_expensive_computation();
let result = rx.recv();
# fn some_expensive_computation() -> int { 42 }
# fn some_other_expensive_computation() {}

fn some_expensive_computation() -> u32 { 42 } // very expensive ;)
fn some_other_expensive_computation() {} // even more so
```

Let's examine this example in detail. First, the `let` statement creates a
stream for sending and receiving integers (the left-hand side of the `let`,
`(tx, rx)`, is an example of a destructuring let: the pattern separates a tuple
into its component parts).

```{rust,ignore}
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
```rust
# use std::sync::mpsc;
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();
```

The child thread will use the sender to send data to the parent thread, which will
wait to receive the data on the receiver. The next statement spawns the child
thread.

```{rust,ignore}
# use std::thread::spawn;
# fn some_expensive_computation() -> int { 42 }
# let (tx, rx) = channel();
spawn(move || {
```rust
# use std::thread::Thread;
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
# let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});
Expand All @@ -125,9 +131,10 @@ computation, then sends the result over the captured channel.
Finally, the parent continues with some other expensive computation, then waits
for the child's result to arrive on the receiver:

```{rust,ignore}
```rust
# use std::sync::mpsc;
# fn some_other_expensive_computation() {}
# let (tx, rx) = channel::<int>();
# let (tx, rx) = mpsc::channel::<u32>();
# tx.send(0);
some_other_expensive_computation();
let result = rx.recv();
Expand All @@ -140,8 +147,9 @@ single `Receiver` value. What if our example needed to compute multiple
results across a number of threads? The following program is ill-typed:

```{rust,ignore}
# fn some_expensive_computation() -> int { 42 }
let (tx, rx) = channel();
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
let (tx, rx) = mpsc::channel();

spawn(move || {
tx.send(some_expensive_computation());
Expand All @@ -156,19 +164,22 @@ spawn(move || {

Instead we can clone the `tx`, which allows for multiple senders.

```{rust,ignore}
let (tx, rx) = channel();
```rust
use std::thread::Thread;
use std::sync::mpsc;

let (tx, rx) = mpsc::channel();

for init_val in range(0u, 3) {
for init_val in 0 .. 3 {
// Create a new channel handle to distribute to the child thread
let child_tx = tx.clone();
spawn(move || {
Thread::spawn(move || {
child_tx.send(some_expensive_computation(init_val));
});
}

let result = rx.recv() + rx.recv() + rx.recv();
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap();
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```

Cloning a `Sender` produces a new handle to the same channel, allowing multiple
Expand All @@ -181,21 +192,22 @@ Note that the above cloning example is somewhat contrived since you could also
simply use three `Sender` pairs, but it serves to illustrate the point. For
reference, written with multiple streams, it might look like the example below.

```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;

// Create a vector of ports, one for each child thread
let rxs = Vec::from_fn(3, |init_val| {
let (tx, rx) = channel();
spawn(move || {
let rxs = (0 .. 3).map(|&:init_val| {
let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
tx.send(some_expensive_computation(init_val));
});
rx
});
}).collect::<Vec<_>>();

// Wait on each port, accumulating the results
let result = rxs.iter().fold(0, |accum, rx| accum + rx.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() );
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```

## Backgrounding computations: Futures
Expand Down
1 change: 0 additions & 1 deletion src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@
//! }
//! # fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] }
//! }
//! # fn main() { }
//! ```
//!
//! ## Mutating implementations of `clone`
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/finally.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@
//!
//! use std::finally::Finally;
//!
//! # fn main() {
//! (|&mut:| {
//! // ...
//! }).finally(|| {
//! // this code is always run
//! })
//! # }
//! ```

#![deprecated = "It is unclear if this module is more robust than implementing \
Expand Down
17 changes: 11 additions & 6 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ macro_rules! panic {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// assert!(true);
/// # fn some_computation() -> bool { true }
///
/// fn some_computation() -> bool { true } // a very simple function
///
/// assert!(some_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3i; let b = 27i;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
Expand Down Expand Up @@ -108,13 +111,15 @@ macro_rules! assert_eq {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// debug_assert!(true);
/// # fn some_expensive_computation() -> bool { true }
///
/// fn some_expensive_computation() -> bool { true } // a very simple function
/// debug_assert!(some_expensive_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// debug_assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3; let b = 27;
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
Expand Down
3 changes: 1 addition & 2 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,7 @@ impl<T: ?Sized> Clone for ContravariantType<T> {
/// "interior" mutability:
///
/// ```
/// pub struct Cell<T> { value: T }
/// # fn main() {}
/// struct Cell<T> { value: T }
/// ```
///
/// The type system would infer that `value` is only read here and
Expand Down
4 changes: 0 additions & 4 deletions src/libcore/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@
//! # Example
//!
//! ```ignore
//! # fn main() {
//! #![feature(globs)]
//!
//! use core::prelude::*;
//! # }
//! ```

// Reexported core operators
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,9 @@
//! makes it clear:
//!
//! ```
//! # #![feature(macro_rules)]
//! macro_rules! try {
//! ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
//! }
//! # fn main() { }
//! ```
//!
//! `try!` is imported by the prelude, and is available everywhere.
Expand Down
11 changes: 2 additions & 9 deletions src/libstd/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@
//!
//! Some examples of the `format!` extension are:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("Hello"); // => "Hello"
//! format!("Hello, {}!", "world"); // => "Hello, world!"
//! format!("The number is {}", 1i); // => "The number is 1"
//! format!("{:?}", (3i, 4i)); // => "(3i, 4i)"
//! format!("{value}", value=4i); // => "4"
//! format!("{} {}", 1i, 2u); // => "1 2"
//! # }
//! ```
//!
//! From these, you can see that the first argument is a format string. It is
Expand Down Expand Up @@ -83,12 +81,10 @@
//!
//! For example, the following `format!` expressions all use named argument:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("{argument}", argument = "test"); // => "test"
//! format!("{name} {}", 1i, name = 2i); // => "2 1"
//! format!("{a} {c} {b}", a="a", b='b', c=3i); // => "a 3 b"
//! # }
//! ```
//!
//! It is illegal to put positional parameters (those without names) after
Expand Down Expand Up @@ -288,8 +284,6 @@
//! use std::fmt;
//! use std::io;
//!
//! # #[allow(unused_must_use)]
//! # fn main() {
//! fmt::format(format_args!("this returns {}", "String"));
//!
//! let some_writer: &mut io::Writer = &mut io::stdout();
Expand All @@ -299,7 +293,6 @@
//! write!(&mut io::stdout(), "{}", args);
//! }
//! my_fmt_fn(format_args!("or a {} too", "function"));
//! # }
//! ```
//!
//! The result of the `format_args!` macro is a value of type `fmt::Arguments`.
Expand Down
27 changes: 11 additions & 16 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,16 +934,15 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// A `RefReader` is a struct implementing `Reader` which contains a reference
/// to another reader. This is often useful when composing streams.
///
/// # Example
/// # Examples
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo() {
/// use std::io;
/// use std::io::ByRefReader;
/// use std::io::util::LimitReader;
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut stream = io::stdin();
///
/// // Only allow the function to process at most one kilobyte of input
Expand All @@ -953,8 +952,6 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// }
///
/// // 'stream' is still available for use here
///
/// # }
/// ```
pub struct RefReader<'a, R:'a> {
/// The underlying reader which this is referencing
Expand Down Expand Up @@ -1269,12 +1266,11 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo () {
/// use std::io::util::TeeReader;
/// use std::io::{stdin, ByRefWriter};
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut output = Vec::new();
///
/// {
Expand All @@ -1285,7 +1281,6 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// }
///
/// println!("input processed: {:?}", output);
/// # }
/// ```
pub struct RefWriter<'a, W:'a> {
/// The underlying writer which this is referencing
Expand Down Expand Up @@ -1705,19 +1700,19 @@ pub enum FileType {
/// A structure used to describe metadata information about a file. This
/// structure is created through the `stat` method on a `Path`.
///
/// # Example
/// # Examples
///
/// ```no_run
/// # #![allow(unstable)]
///
/// use std::io::fs::PathExtensions;
///
/// ```
/// # use std::io::fs::PathExtensions;
/// # fn main() {}
/// # fn foo() {
/// let info = match Path::new("foo.txt").stat() {
/// Ok(stat) => stat,
/// Err(e) => panic!("couldn't read foo.txt: {}", e),
/// };
///
/// println!("byte size: {}", info.size);
/// # }
/// ```
#[derive(Copy, Hash)]
pub struct FileStat {
Expand Down
2 changes: 0 additions & 2 deletions src/libstd/io/net/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,7 @@ impl UnixListener {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// # #![allow(unused_must_use)]
/// use std::io::net::pipe::UnixListener;
/// use std::io::{Listener, Acceptor};
///
Expand Down
Loading