-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Write the 'primitive types' section of TRPL
A brief introduction to each type, with pointers to the primitive pages for more info.
- Loading branch information
1 parent
e57410c
commit 7bb0cd7
Showing
5 changed files
with
267 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,268 @@ | ||
% Primitive Types | ||
|
||
Coming Soon! | ||
The Rust language has a number of types that are considered ‘primitive’. This | ||
means that they’re built-in to the language. Rust is structured in such a way | ||
that the standard library also provides a number of useful types built on top | ||
of these ones, as well, but these are the most primitive. | ||
|
||
# Booleans | ||
|
||
Rust has a built in boolean type, named `bool`. It has two values, `true` and `false`: | ||
|
||
```rust | ||
let x = true; | ||
|
||
let y: bool = false; | ||
``` | ||
|
||
A common use of booleans is in [`if` statements][if]. | ||
|
||
[if]: if.html | ||
|
||
You can find more documentation for `bool`s [in the standard library | ||
documentation][bool]. | ||
|
||
[bool]: ../std/primitive.bool.html | ||
|
||
# `char` | ||
|
||
The `char` type represents a single Unicode scalar value. You can create `char`s | ||
with a single tick: (`'`) | ||
|
||
```rust | ||
let x = 'x'; | ||
let two_hearts = '💕'; | ||
``` | ||
|
||
Unlike some other languages, this means that Rust’s `char` is not a single byte, | ||
but four. | ||
|
||
You can find more documentation for `char`s [in the standard library | ||
documentation][char]. | ||
|
||
[char]: ../std/primitive.char.html | ||
|
||
# Numeric types | ||
|
||
Rust has a variety of numeric types in a few categories: signed and unsigned, | ||
fixed and variable, floating-point and integer. | ||
|
||
These types consist of two parts: the category, and the size. For example, | ||
`u16` is an unsigned type with sixteen bits of size. More bits lets you have | ||
bigger numbers. | ||
|
||
If a number literal has nothing to cause its type to be inferred, it defaults: | ||
|
||
```rust | ||
let x = 42; // x has type i32 | ||
|
||
let y = 1.0; // y has type f64 | ||
``` | ||
|
||
Here’s a list of the different numeric types, with links to their documentation | ||
in the standard library: | ||
|
||
* [i16](../std/primitive.i16.html) | ||
* [i32](../std/primitive.i32.html) | ||
* [i64](../std/primitive.i64.html) | ||
* [i8](../std/primitive.i8.html) | ||
* [u16](../std/primitive.u16.html) | ||
* [u32](../std/primitive.u32.html) | ||
* [u64](../std/primitive.u64.html) | ||
* [u8](../std/primitive.u8.html) | ||
* [isize](../std/primitive.isize.html) | ||
* [usize](../std/primitive.usize.html) | ||
* [f32](../std/primitive.f32.html) | ||
* [f64](../std/primitive.f64.html) | ||
|
||
Let’s go over them by category: | ||
|
||
## Signed and Unsigned | ||
|
||
Integer types come in two varieties: signed and unsigned. To understand the | ||
difference, let’s consider a number with four bits of size. A signed, four-bit | ||
number would let you store numbers from `-8` to `+7`. Signed numbers use | ||
‘two’s compliment representation’. An unsigned four bit number, since it does | ||
not need to store negatives, can store values from `0` to `+15`. | ||
|
||
Unsigned types use a `u` for their category, and signed types use `i`. The `i` | ||
is for ‘integer’. So `u8` is an eight-bit unsigned number, and `i8` is an | ||
eight-bit signed number. | ||
|
||
## Fixed size types | ||
|
||
Fixed size types have a specific number of bits in their representation. Valid | ||
bit sizes are `8`, `16`, `32`, and `64`. So, `u32` is an unsigned, 32-bit integer, | ||
and `i64` is a signed, 64-bit integer. | ||
|
||
## Variable sized types | ||
|
||
Rust also provides types whose size depends on the size of a pointer of the | ||
underlying machine. These types have ‘size’ as the category, and come in signed | ||
and unsigned varieties. This makes for two types: `isize` and `usize`. | ||
|
||
## Floating-point types | ||
|
||
Rust also two floating point types: `f32` and `f64`. These correspond to | ||
IEEE-754 single and double precision numbers. | ||
|
||
# Arrays | ||
|
||
Like many programming languages, Rust has list types to represent a sequence of | ||
things. The most basic is the *array*, a fixed-size list of elements of the | ||
same type. By default, arrays are immutable. | ||
|
||
```rust | ||
let a = [1, 2, 3]; // a: [i32; 3] | ||
let mut m = [1, 2, 3]; // m: [i32; 3] | ||
``` | ||
|
||
Arrays have type `[T; N]`. We’ll talk about this `T` notation [in the generics | ||
section][generics]. The `N` is a compile-time constant, for the length of the | ||
array. | ||
|
||
There’s a shorthand for initializing each element of an array to the same | ||
value. In this example, each element of `a` will be initialized to `0`: | ||
|
||
```rust | ||
let a = [0; 20]; // a: [i32; 20] | ||
``` | ||
|
||
You can get the number of elements in an array `a` with `a.len()`: | ||
|
||
```rust | ||
let a = [1, 2, 3]; | ||
|
||
println!("a has {} elements", a.len()); | ||
``` | ||
|
||
You can access a particular element of an array with *subscript notation*: | ||
|
||
```rust | ||
let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3] | ||
|
||
println!("The second name is: {}", names[1]); | ||
``` | ||
|
||
Subscripts start at zero, like in most programming languages, so the first name | ||
is `names[0]` and the second name is `names[1]`. The above example prints | ||
`The second name is: Brian`. If you try to use a subscript that is not in the | ||
array, you will get an error: array access is bounds-checked at run-time. Such | ||
errant access is the source of many bugs in other systems programming | ||
languages. | ||
|
||
You can find more documentation for `array`s [in the standard library | ||
documentation][array]. | ||
|
||
[array]: ../std/primitive.array.html | ||
|
||
# Slices | ||
|
||
A ‘slice’ is a reference to (or “view” into) another data structure. They are | ||
useful for allowing safe, efficient access to a portion of an array without | ||
copying. For example, you might want to reference just one line of a file read | ||
into memory. By nature, a slice is not created directly, but from an existing | ||
variable. Slices have a length, can be mutable or not, and in many ways behave | ||
like arrays: | ||
|
||
```rust | ||
let a = [0, 1, 2, 3, 4]; | ||
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3 | ||
``` | ||
|
||
Slices have type `&[T]`. We’ll talk about that `T` when we cover | ||
[generics][generics]. | ||
|
||
[generics]: generics.html | ||
|
||
You can find more documentation for `slices`s [in the standard library | ||
documentation][slice]. | ||
|
||
[slice]: ../std/primitive.slice.html | ||
|
||
# `str` | ||
|
||
Rust’s `str` type is the most primitive string type. As an [unsized type][dst], | ||
it’s not very useful by itself, but becomes useful when placed behind a reference, | ||
like [`&str`][strings]. As such, we’ll just leave it at that. | ||
|
||
[dst]: unsized-types.html | ||
[strings]: strings.html | ||
|
||
You can find more documentation for `str` [in the standard library | ||
documentation][str]. | ||
|
||
[str]: ../std/primitive.str.html | ||
|
||
# Tuples | ||
|
||
A tuple is an ordered list of fixed size. Like this: | ||
|
||
```rust | ||
let x = (1, "hello"); | ||
``` | ||
|
||
The parentheses and commas form this two-length tuple. Here’s the same code, but | ||
with the type annotated: | ||
|
||
```rust | ||
let x: (i32, &str) = (1, "hello"); | ||
``` | ||
|
||
As you can see, the type of a tuple looks just like the tuple, but with each | ||
position having a type name rather than the value. Careful readers will also | ||
note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple. | ||
In systems programming languages, strings are a bit more complex than in other | ||
languages. For now, just read `&str` as a *string slice*, and we’ll learn more | ||
soon. | ||
|
||
You can access the fields in a tuple through a *destructuring let*. Here’s | ||
an example: | ||
|
||
```rust | ||
let (x, y, z) = (1, 2, 3); | ||
|
||
println!("x is {}", x); | ||
``` | ||
|
||
Remember [before][let] when I said the left-hand side of a `let` statement was more | ||
powerful than just assigning a binding? Here we are. We can put a pattern on | ||
the left-hand side of the `let`, and if it matches up to the right-hand side, | ||
we can assign multiple bindings at once. In this case, `let` "destructures," | ||
or "breaks up," the tuple, and assigns the bits to three bindings. | ||
|
||
[let]: variable-bindings.html | ||
|
||
This pattern is very powerful, and we’ll see it repeated more later. | ||
|
||
There are also a few things you can do with a tuple as a whole, without | ||
destructuring. You can assign one tuple into another, if they have the same | ||
contained types and [arity]. Tuples have the same arity when they have the same | ||
length. | ||
|
||
[arity]: glossary.html#arity | ||
|
||
```rust | ||
let mut x = (1, 2); // x: (i32, i32) | ||
let y = (2, 3); // y: (i32, i32) | ||
|
||
x = y; | ||
``` | ||
|
||
You can find more documentation for tuples [in the standard library | ||
documentation][tuple]. | ||
|
||
[tuple]: ../std/primitive.tuple.html | ||
|
||
# Functions | ||
|
||
Functions also have a type! They look like this: | ||
|
||
``` | ||
fn foo(x: i32) -> i32 { x } | ||
let x: fn(i32) -> i32 = foo; | ||
``` | ||
|
||
In this case, `x` is a ‘function pointer’ to a function that takes an `i32` and | ||
returns an `i32`. |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.