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