]> git.proxmox.com Git - rustc.git/blame - src/doc/book/src/ch10-00-generics.md
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / src / ch10-00-generics.md
CommitLineData
13cf67c4
XL
1# Generic Types, Traits, and Lifetimes
2
3Every programming language has tools for effectively handling the duplication
5e7ed085
FG
4of concepts. In Rust, one such tool is *generics*: abstract stand-ins for
5concrete types or other properties. We can express the behavior of generics or
6how they relate to other generics without knowing what will be in their place
7when compiling and running the code.
8
9Functions can take parameters of some generic type, instead of a concrete type
10like `i32` or `String`, in the same way a function takes parameters with
11unknown values to run the same code on multiple concrete values. In fact, we’ve
13cf67c4
XL
12already used generics in Chapter 6 with `Option<T>`, Chapter 8 with `Vec<T>`
13and `HashMap<K, V>`, and Chapter 9 with `Result<T, E>`. In this chapter, you’ll
14explore how to define your own types, functions, and methods with generics!
15
5e7ed085
FG
16First, we’ll review how to extract a function to reduce code duplication. We’ll
17then use the same technique to make a generic function from two functions that
13cf67c4
XL
18differ only in the types of their parameters. We’ll also explain how to use
19generic types in struct and enum definitions.
20
21Then you’ll learn how to use *traits* to define behavior in a generic way. You
5e7ed085
FG
22can combine traits with generic types to constrain a generic type to accept
23only those types that have a particular behavior, as opposed to just any type.
13cf67c4 24
5e7ed085 25Finally, we’ll discuss *lifetimes*: a variety of generics that give the
13cf67c4 26compiler information about how references relate to each other. Lifetimes allow
5e7ed085
FG
27us to give the compiler enough information about borrowed values so that it can
28ensure references will be valid in more situations than it could without our
29help.
13cf67c4
XL
30
31## Removing Duplication by Extracting a Function
32
5e7ed085
FG
33Generics allow us to replace specific types with a placeholder that represents
34multiple types to remove code duplication. Before diving into generics syntax,
35then, let’s first look at how to remove duplication in a way that doesn’t
36involve generic types by extracting a function that replaces specific values
37with a placeholder that represents multiple values. Then we’ll apply the same
38technique to extract a generic function! By looking at how to recognize
39duplicated code you can extract into a function, you’ll start to recognize
40duplicated code that can use generics.
13cf67c4 41
5e7ed085
FG
42We begin with the short program in Listing 10-1 that finds the largest number
43in a list.
13cf67c4
XL
44
45<span class="filename">Filename: src/main.rs</span>
46
47```rust
74b04a01 48{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs:here}}
13cf67c4
XL
49```
50
5e7ed085
FG
51<span class="caption">Listing 10-1: Finding the largest number in a list of
52numbers</span>
13cf67c4 53
923072b8
FG
54We store a list of integers in the variable `number_list` and place a reference
55to the first number in the list in a variable named `largest`. We then iterate
56through all the numbers in the list, and if the current number is greater than
57the number stored in `largest`, replace the reference in that variable.
58However, if the current number is less than or equal to the largest number seen
59so far, the variable doesn’t change, and the code moves on to the next number
60in the list. After considering all the numbers in the list, `largest` should
61refer to the largest number, which in this case is 100.
13cf67c4 62
5e7ed085
FG
63We've now been tasked with finding the largest number in two different lists of
64numbers. To do so, we can choose to duplicate the code in Listing 10-1 and use
65the same logic at two different places in the program, as shown in Listing 10-2.
13cf67c4
XL
66
67<span class="filename">Filename: src/main.rs</span>
68
69```rust
74b04a01 70{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs}}
13cf67c4
XL
71```
72
73<span class="caption">Listing 10-2: Code to find the largest number in *two*
74lists of numbers</span>
75
76Although this code works, duplicating code is tedious and error prone. We also
5e7ed085
FG
77have to remember to update the code in multiple places when we want to change
78it.
13cf67c4 79
5e7ed085
FG
80To eliminate this duplication, we’ll create an abstraction by defining a
81function that operates on any list of integers passed in a parameter. This
13cf67c4
XL
82solution makes our code clearer and lets us express the concept of finding the
83largest number in a list abstractly.
84
5e7ed085
FG
85In Listing 10-3, we extract the code that finds the largest number into a
86function named `largest`. Then we call the function to find the largest number
87in the two lists from Listing 10-2. We could also use the function on any other
88list of `i32` values we might have in the future.
13cf67c4
XL
89
90<span class="filename">Filename: src/main.rs</span>
91
92```rust
74b04a01 93{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs:here}}
13cf67c4
XL
94```
95
96<span class="caption">Listing 10-3: Abstracted code to find the largest number
97in two lists</span>
98
99The `largest` function has a parameter called `list`, which represents any
5e7ed085
FG
100concrete slice of `i32` values we might pass into the function. As a result,
101when we call the function, the code runs on the specific values that we pass
923072b8 102in.
13cf67c4 103
923072b8 104In summary, here are the steps we took to change the code from Listing 10-2 to
13cf67c4
XL
105Listing 10-3:
106
1071. Identify duplicate code.
1082. Extract the duplicate code into the body of the function and specify the
109 inputs and return values of that code in the function signature.
1103. Update the two instances of duplicated code to call the function instead.
111
5e7ed085
FG
112Next, we’ll use these same steps with generics to reduce code duplication. In
113the same way that the function body can operate on an abstract `list` instead
114of specific values, generics allow code to operate on abstract types.
13cf67c4
XL
115
116For example, say we had two functions: one that finds the largest item in a
117slice of `i32` values and one that finds the largest item in a slice of `char`
118values. How would we eliminate that duplication? Let’s find out!