Auto merge of #39748 - Rufflewind:master, r=steveklabnik
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.
This commit is contained in:
commit
5b7c556385
@ -140,5 +140,51 @@ container types like [`Vec<T>`][Vec]. On the other hand, often you want to
|
|||||||
trade that flexibility for increased expressive power. Read about [trait
|
trade that flexibility for increased expressive power. Read about [trait
|
||||||
bounds][traits] to see why and how.
|
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<T> 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<bool> = Vec::new();
|
||||||
|
println!("{:?}", v);
|
||||||
|
```
|
||||||
|
|
||||||
|
or by binding the generic parameter `T` via the so-called
|
||||||
|
[‘turbofish’][turbofish] `::<>` syntax:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let v = Vec::<bool>::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
|
[traits]: traits.html
|
||||||
[Vec]: ../std/vec/struct.Vec.html
|
[Vec]: ../std/vec/struct.Vec.html
|
||||||
|
[turbofish]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect
|
||||||
|
@ -135,10 +135,10 @@ Here's the version that does compile:
|
|||||||
let one_to_one_hundred = (1..101).collect::<Vec<i32>>();
|
let one_to_one_hundred = (1..101).collect::<Vec<i32>>();
|
||||||
```
|
```
|
||||||
|
|
||||||
If you remember, the `::<>` syntax allows us to give a type hint,
|
If you remember, the [`::<>` syntax](generics.html#resolving-ambiguities)
|
||||||
and so we tell it that we want a vector of integers. You don't always
|
allows us to give a type hint that tells the compiler we want a vector of
|
||||||
need to use the whole type, though. Using a `_` will let you provide
|
integers. You don't always need to use the whole type, though. Using a `_`
|
||||||
a partial hint:
|
will let you provide a partial hint:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let one_to_one_hundred = (1..101).collect::<Vec<_>>();
|
let one_to_one_hundred = (1..101).collect::<Vec<_>>();
|
||||||
|
@ -134,7 +134,7 @@ fn main() {
|
|||||||
let age = 27;
|
let age = 27;
|
||||||
let peter = Person { name, age };
|
let peter = Person { name, age };
|
||||||
|
|
||||||
// Print debug struct
|
// Debug-print struct
|
||||||
println!("{:?}", peter);
|
println!("{:?}", peter);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
<!-- Generics -->
|
<!-- Generics -->
|
||||||
|
|
||||||
* `path<…>` (*e.g.* `Vec<u8>`): specifies parameters to generic type *in a type*. See [Generics].
|
* `path<…>` (*e.g.* `Vec<u8>`): specifies parameters to generic type *in a type*. See [Generics].
|
||||||
* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::<i32>()`): specifies parameters to generic type, function, or method *in an expression*.
|
* `path::<…>`, `method::<…>` (*e.g.* `"42".parse::<i32>()`): 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].
|
* `fn ident<…> …`: define generic function. See [Generics].
|
||||||
* `struct ident<…> …`: define generic structure. See [Generics].
|
* `struct ident<…> …`: define generic structure. See [Generics].
|
||||||
* `enum ident<…> …`: define generic enumeration. See [Generics].
|
* `enum ident<…> …`: define generic enumeration. See [Generics].
|
||||||
|
Loading…
Reference in New Issue
Block a user