]> git.proxmox.com Git - rustc.git/blob - src/doc/book/primitive-types.md
New upstream version 1.15.0+dfsg1
[rustc.git] / src / doc / book / primitive-types.md
1 % Primitive Types
2
3 The Rust language has a number of types that are considered ‘primitive’. This
4 means that they’re built-in to the language. Rust is structured in such a way
5 that the standard library also provides a number of useful types built on top
6 of these ones, as well, but these are the most primitive.
7
8 # Booleans
9
10 Rust has a built-in boolean type, named `bool`. It has two values, `true` and `false`:
11
12 ```rust
13 let x = true;
14
15 let y: bool = false;
16 ```
17
18 A common use of booleans is in [`if` conditionals][if].
19
20 [if]: if.html
21
22 You can find more documentation for `bool`s [in the standard library
23 documentation][bool].
24
25 [bool]: ../std/primitive.bool.html
26
27 # `char`
28
29 The `char` type represents a single Unicode scalar value. You can create `char`s
30 with a single tick: (`'`)
31
32 ```rust
33 let x = 'x';
34 let two_hearts = '💕';
35 ```
36
37 Unlike some other languages, this means that Rust’s `char` is not a single byte,
38 but four.
39
40 You can find more documentation for `char`s [in the standard library
41 documentation][char].
42
43 [char]: ../std/primitive.char.html
44
45 # Numeric types
46
47 Rust has a variety of numeric types in a few categories: signed and unsigned,
48 fixed and variable, floating-point and integer.
49
50 These types consist of two parts: the category, and the size. For example,
51 `u16` is an unsigned type with sixteen bits of size. More bits lets you have
52 bigger numbers.
53
54 If a number literal has nothing to cause its type to be inferred, it defaults:
55
56 ```rust
57 let x = 42; // `x` has type `i32`.
58
59 let y = 1.0; // `y` has type `f64`.
60 ```
61
62 Here’s a list of the different numeric types, with links to their documentation
63 in the standard library:
64
65 * [i8](../std/primitive.i8.html)
66 * [i16](../std/primitive.i16.html)
67 * [i32](../std/primitive.i32.html)
68 * [i64](../std/primitive.i64.html)
69 * [u8](../std/primitive.u8.html)
70 * [u16](../std/primitive.u16.html)
71 * [u32](../std/primitive.u32.html)
72 * [u64](../std/primitive.u64.html)
73 * [isize](../std/primitive.isize.html)
74 * [usize](../std/primitive.usize.html)
75 * [f32](../std/primitive.f32.html)
76 * [f64](../std/primitive.f64.html)
77
78 Let’s go over them by category:
79
80 ## Signed and Unsigned
81
82 Integer types come in two varieties: signed and unsigned. To understand the
83 difference, let’s consider a number with four bits of size. A signed, four-bit
84 number would let you store numbers from `-8` to `+7`. Signed numbers use
85 “two’s complement representation”. An unsigned four bit number, since it does
86 not need to store negatives, can store values from `0` to `+15`.
87
88 Unsigned types use a `u` for their category, and signed types use `i`. The `i`
89 is for ‘integer’. So `u8` is an eight-bit unsigned number, and `i8` is an
90 eight-bit signed number.
91
92 ## Fixed-size types
93
94 Fixed-size types have a specific number of bits in their representation. Valid
95 bit sizes are `8`, `16`, `32`, and `64`. So, `u32` is an unsigned, 32-bit integer,
96 and `i64` is a signed, 64-bit integer.
97
98 ## Variable-size types
99
100 Rust also provides types whose particular size depends on the underlying machine
101 architecture. Their range is sufficient to express the size of any collection, so
102 these types have ‘size’ as the category. They come in signed and unsigned varieties
103 which account for two types: `isize` and `usize`.
104
105 ## Floating-point types
106
107 Rust also has two floating point types: `f32` and `f64`. These correspond to
108 IEEE-754 single and double precision numbers.
109
110 # Arrays
111
112 Like many programming languages, Rust has list types to represent a sequence of
113 things. The most basic is the *array*, a fixed-size list of elements of the
114 same type. By default, arrays are immutable.
115
116 ```rust
117 let a = [1, 2, 3]; // a: [i32; 3]
118 let mut m = [1, 2, 3]; // m: [i32; 3]
119 ```
120
121 Arrays have type `[T; N]`. We’ll talk about this `T` notation [in the generics
122 section][generics]. The `N` is a compile-time constant, for the length of the
123 array.
124
125 There’s a shorthand for initializing each element of an array to the same
126 value. In this example, each element of `a` will be initialized to `0`:
127
128 ```rust
129 let a = [0; 20]; // a: [i32; 20]
130 ```
131
132 You can get the number of elements in an array `a` with `a.len()`:
133
134 ```rust
135 let a = [1, 2, 3];
136
137 println!("a has {} elements", a.len());
138 ```
139
140 You can access a particular element of an array with *subscript notation*:
141
142 ```rust
143 let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]
144
145 println!("The second name is: {}", names[1]);
146 ```
147
148 Subscripts start at zero, like in most programming languages, so the first name
149 is `names[0]` and the second name is `names[1]`. The above example prints
150 `The second name is: Brian`. If you try to use a subscript that is not in the
151 array, you will get an error: array access is bounds-checked at run-time. Such
152 errant access is the source of many bugs in other systems programming
153 languages.
154
155 You can find more documentation for `array`s [in the standard library
156 documentation][array].
157
158 [array]: ../std/primitive.array.html
159
160 # Slices
161
162 A ‘slice’ is a reference to (or “view” into) another data structure. They are
163 useful for allowing safe, efficient access to a portion of an array without
164 copying. For example, you might want to reference only one line of a file read
165 into memory. By nature, a slice is not created directly, but from an existing
166 variable binding. Slices have a defined length, and can be mutable or immutable.
167
168 Internally, slices are represented as a pointer to the beginning of the data
169 and a length.
170
171 ## Slicing syntax
172
173 You can use a combo of `&` and `[]` to create a slice from various things. The
174 `&` indicates that slices are similar to [references], which we will cover in
175 detail later in this section. The `[]`s, with a range, let you define the
176 length of the slice:
177
178 ```rust
179 let a = [0, 1, 2, 3, 4];
180 let complete = &a[..]; // A slice containing all of the elements in `a`.
181 let middle = &a[1..4]; // A slice of `a`: only the elements `1`, `2`, and `3`.
182 ```
183
184 Slices have type `&[T]`. We’ll talk about that `T` when we cover
185 [generics][generics].
186
187 [generics]: generics.html
188
189 You can find more documentation for slices [in the standard library
190 documentation][slice].
191
192 [slice]: ../std/primitive.slice.html
193
194 # `str`
195
196 Rust’s `str` type is the most primitive string type. As an [unsized type][dst],
197 it’s not very useful by itself, but becomes useful when placed behind a
198 reference, like `&str`. We'll elaborate further when we cover
199 [Strings][strings] and [references].
200
201 [dst]: unsized-types.html
202 [strings]: strings.html
203 [references]: references-and-borrowing.html
204
205 You can find more documentation for `str` [in the standard library
206 documentation][str].
207
208 [str]: ../std/primitive.str.html
209
210 # Tuples
211
212 A tuple is an ordered list of fixed size. Like this:
213
214 ```rust
215 let x = (1, "hello");
216 ```
217
218 The parentheses and commas form this two-length tuple. Here’s the same code, but
219 with the type annotated:
220
221 ```rust
222 let x: (i32, &str) = (1, "hello");
223 ```
224
225 As you can see, the type of a tuple looks like the tuple, but with each
226 position having a type name rather than the value. Careful readers will also
227 note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple.
228 In systems programming languages, strings are a bit more complex than in other
229 languages. For now, read `&str` as a *string slice*, and we’ll learn more
230 soon.
231
232 You can assign one tuple into another, if they have the same contained types
233 and [arity]. Tuples have the same arity when they have the same length.
234
235 [arity]: glossary.html#arity
236
237 ```rust
238 let mut x = (1, 2); // x: (i32, i32)
239 let y = (2, 3); // y: (i32, i32)
240
241 x = y;
242 ```
243
244 You can access the fields in a tuple through a *destructuring let*. Here’s
245 an example:
246
247 ```rust
248 let (x, y, z) = (1, 2, 3);
249
250 println!("x is {}", x);
251 ```
252
253 Remember [before][let] when I said the left-hand side of a `let` statement was more
254 powerful than assigning a binding? Here we are. We can put a pattern on
255 the left-hand side of the `let`, and if it matches up to the right-hand side,
256 we can assign multiple bindings at once. In this case, `let` “destructures”
257 or “breaks up” the tuple, and assigns the bits to three bindings.
258
259 [let]: variable-bindings.html
260
261 This pattern is very powerful, and we’ll see it repeated more later.
262
263 You can disambiguate a single-element tuple from a value in parentheses with a
264 comma:
265
266 ```rust
267 (0,); // A single-element tuple.
268 (0); // A zero in parentheses.
269 ```
270
271 ## Tuple Indexing
272
273 You can also access fields of a tuple with indexing syntax:
274
275
276 ```rust
277 let tuple = (1, 2, 3);
278
279 let x = tuple.0;
280 let y = tuple.1;
281 let z = tuple.2;
282
283 println!("x is {}", x);
284 ```
285
286 Like array indexing, it starts at zero, but unlike array indexing, it uses a
287 `.`, rather than `[]`s.
288
289 You can find more documentation for tuples [in the standard library
290 documentation][tuple].
291
292 [tuple]: ../std/primitive.tuple.html
293
294 # Functions
295
296 Functions also have a type! They look like this:
297
298 ```rust
299 fn foo(x: i32) -> i32 { x }
300
301 let x: fn(i32) -> i32 = foo;
302 ```
303
304 In this case, `x` is a ‘function pointer’ to a function that takes an `i32` and
305 returns an `i32`.