From cc000599b8f3fd2b15a7d862bd70da440ff8b12b Mon Sep 17 00:00:00 2001 From: Phil Ruffwind Date: Sat, 11 Feb 2017 17:00:56 -0500 Subject: [PATCH] Rust Book: Generics: Resolving ambiguities - Add a small section to generics.md to explain how ambiguities in type inference can be resolved using the ::<> syntax. - Add links from syntax-index.md and iterators.md. - Minor edits to iterators.md and structs.md. --- src/doc/book/src/generics.md | 46 ++++++++++++++++++++++++++++++++ src/doc/book/src/iterators.md | 8 +++--- src/doc/book/src/structs.md | 2 +- src/doc/book/src/syntax-index.md | 2 +- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/doc/book/src/generics.md b/src/doc/book/src/generics.md index 56655ac41d0d3..d02cd776d00e3 100644 --- a/src/doc/book/src/generics.md +++ b/src/doc/book/src/generics.md @@ -140,5 +140,51 @@ container types like [`Vec`][Vec]. On the other hand, often you want to trade that flexibility for increased expressive power. Read about [trait bounds][traits] to see why and how. +## Resolving ambiguities + +Most of the time when generics are involved, the compiler can infer the +generic parameters automatically: + +```rust +// v must be a Vec but we don't know what T is yet +let mut v = Vec::new(); +// v just got a bool value, so T must be bool! +v.push(true); +// Debug-print v +println!("{:?}", v); +``` + +Sometimes though, the compiler needs a little help. For example, had we +omitted the last line, we would get a compile error: + +```rust,ignore +let v = Vec::new(); +// ^^^^^^^^ cannot infer type for `T` +// +// note: type annotations or generic parameter binding required +println!("{:?}", v); +``` + +We can solve this using either a type annotation: + +```rust +let v: Vec = Vec::new(); +println!("{:?}", v); +``` + +or by binding the generic parameter `T` via the so-called +[‘turbofish’][turbofish] `::<>` syntax: + +```rust +let v = Vec::::new(); +println!("{:?}", v); +``` + +The second approach is useful in situations where we don’t want to bind the +result to a variable. It can also be used to bind generic parameters in +functions or methods. See [Iterators § Consumers](iterators.html#consumers) +for an example. + [traits]: traits.html [Vec]: ../std/vec/struct.Vec.html +[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect diff --git a/src/doc/book/src/iterators.md b/src/doc/book/src/iterators.md index 1437c0f0b54c6..8ee6c0828ad6b 100644 --- a/src/doc/book/src/iterators.md +++ b/src/doc/book/src/iterators.md @@ -135,10 +135,10 @@ Here's the version that does compile: let one_to_one_hundred = (1..101).collect::>(); ``` -If you remember, the `::<>` syntax allows us to give a type hint, -and so we tell it that we want a vector of integers. You don't always -need to use the whole type, though. Using a `_` will let you provide -a partial hint: +If you remember, the [`::<>` syntax](generics.html#resolving-ambiguities) +allows us to give a type hint that tells the compiler we want a vector of +integers. You don't always need to use the whole type, though. Using a `_` +will let you provide a partial hint: ```rust let one_to_one_hundred = (1..101).collect::>(); diff --git a/src/doc/book/src/structs.md b/src/doc/book/src/structs.md index 6423147e66e09..6b2a145c85e51 100644 --- a/src/doc/book/src/structs.md +++ b/src/doc/book/src/structs.md @@ -134,7 +134,7 @@ fn main() { let age = 27; let peter = Person { name, age }; - // Print debug struct + // Debug-print struct println!("{:?}", peter); } ``` diff --git a/src/doc/book/src/syntax-index.md b/src/doc/book/src/syntax-index.md index 1e1d811a1d8b1..df7ae410ed1c1 100644 --- a/src/doc/book/src/syntax-index.md +++ b/src/doc/book/src/syntax-index.md @@ -125,7 +125,7 @@ * `path<…>` (*e.g.* `Vec`): specifies parameters to generic type *in a type*. See [Generics]. -* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::()`): specifies parameters to generic type, function, or method *in an expression*. +* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::()`): specifies parameters to generic type, function, or method *in an expression*. See [Generics § Resolving ambiguities](generics.html#resolving-ambiguities). * `fn ident<…> …`: define generic function. See [Generics]. * `struct ident<…> …`: define generic structure. See [Generics]. * `enum ident<…> …`: define generic enumeration. See [Generics].