Primitive types
See also: List of primitive types in the standard library documentation
Primitive types are types that are built into the language. Most other types are composed of these primitive types. Primitive types have special syntax – for example, numbers can be created with number literals.
Numeric types
Numeric types are integers (whole numbers) and floating-point numbers. Unsigned integers can never be negative. Signed integers can be negative and are represented as Two's complement.
The floating-point numbers implement the binary32 and binary64 formats specified in IEEE 754. This means that they are represented as a sign bit, an exponent and a fraction. They can be NaN ("not a number") and (–)Infinity. Because NaN is specified to not be equal to itself, floating-point numbers implement the PartialEq
trait, but not Eq
.
Type | Size | Minimum real number | Maximum real number | Precision | |
---|---|---|---|---|---|
Unsigned integers | u8
|
1 byte | 0 | 28 – 1 = 255 | whole numbers |
u16
|
2 bytes | 0 | 216 – 1 = 65,535 | ||
u32
|
4 bytes | 0 | 232 – 1 = 4,294,967,295 | ||
u64
|
8 bytes | 0 | 264 – 1 ≈ 1.845 × 1019 | ||
u128
|
16 bytes | 0 | 2128 – 1 ≈ 3.403 × 1038 | ||
usize
|
Same as a pointer | 0 | Platform dependent | ||
Signed integers | i8
|
1 byte | –27 = –128 | 27 – 1 = 127 | |
i16
|
2 bytes | –215 = –32,768 | 215 – 1 = 32,767 | ||
i32
|
4 bytes | –231 = –2,147,483,648 | 231 – 1 = 2,147,483,647 | ||
i64
|
8 bytes | –263 ≈ –9.223 × 1018 | 263 – 1 ≈ 9.223 × 1018 | ||
i128
|
16 bytes | –2127 ≈ –1.701 × 1038 | 2127 – 1 ≈ 1.701 × 1038 | ||
isize
|
Same as a pointer | Platform dependent | Platform dependent | ||
Floating-point numbers | f32
|
4 bytes | –(2 – 2–23) × 2127 ≈ –3.403 × 1038 | (2 – 2–23) × 2127 ≈ 3.403 × 1038 | 6 to 9 significant decimal digits |
f64
|
8 bytes | –(2 – 2–52) × 21023 ≈ –1.798 × 10308 | (2 – 2–52) × 21023 ≈ 1.798 × 10308 | 15 to 17 significant decimal digits |
Number literals
There are two types of number literals, {integer}
and {float}
; the compiler tries to infer one of the integer types for {integer}
literals and f32
or f64
for {float}
literals. If the type can't be inferred, {integer}
defaults to i32
and {float}
defaults to f64
. It is possible to explicitly specify the type with a suffix, e.g. 4u8
, 0_u32
.
A number literal can contain any number of underscores (_
), as long as it doesn't start with an underscore, and the decimal point isn't immediately followed by an underscore.
Syntactically, the sign is not part of the literal. However, Rust checks if the literal is preceded by a sign, so -(128_i8)
compiles, even though 128_i8 * (-1)
and -{ 128_u8 }
does not.
{float}
literals must contain a decimal point (e.g. 1.5
or 1.
) or an exponent (e.g. (1e2
or 1.5e-2
), or must have a f32
or f64
suffix (e.g. 1f32
).
{integer}
literals can be specified in different formats. The default format is decimal. Hexadecimal literals start with 0x
, octal literals start with 0o
, binary literals with 0b
. The prefix can't contain underscores.
Number literals with a type suffix can be immediately followed by a dot and a method call. For example, 7u8.count_ones()
and 7.5f32.abs()
work.
For u8
exists a special kind of literal, the byte literal, which is a char
literal prefixed with b
, e.g. b'a'
. The character must be in the range 0..=255
. Even though it looks like a character, its type is u8
.
bool
A value that can be true
or false
. true
is represented as 1
, false
is represented as 0
. This type is used for boolean logic. For example if
and while
expressions as well as the &&
, ||
and !
operators operate on bool
values.
Truth tables
NOT (! )
| |
a
|
!a
|
---|---|
true | false |
false | true |
AND (&& )
| ||
a
|
b
|
a && b
|
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
OR (|| )
| ||
a
|
b
|
a || b
|
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
Note: The red values are not evaluated because of short-circuiting.
char
char
is a character of text, or more precisely, a Unicode scalar value. This is similar to, but not the same as a Unicode code point, because a char
may never contain a high-surrogate or low-surrogate code point. char
has a size of 4 bytes.
Note that some char
s aren't visible characters, and what looks like a single character, can consist of multiple char
s.
char
literals
char
literals are char
s surrounded by single quotes (''
). They may contain the following escape sequences:
- Quotes:
\'
and\"
- ASCII escapes:
\0
(null, U+0000)\t
(horizontal tab, U+0009)\n
(line feed, U+000A)\r
(carriage return, U+000D)\\
(backslash, U+005C)\x
followed by an octal digit and a hexadecimal digit, e.g'\x41' == 'A'
- Unicode escapes:
\u{
...}
. Between the braces go 1 to 6 hexadecimal digits. Underscore are allowed as well, e.g.'\u{1E_07}' == 'ḇ'
str
A chunk of UTF-8 encoded text. Because the text can have any length, this is a dynamically-sized type.
str
is not the same as [char]
. While a char
is always 4 bytes wide, characters in a str
have a variable width between 1 and 4 bytes. Lower code points, like ASCII, have a more compact representation than higher code points, such as Chinese characters or emojis.
Because of this, char
s in a string can't be indexed in constant time. Furthermore, the str::len()
method returns the length in bytes, not in characters.
String literals
String literals have the type &'static str
. They have the 'static
lifetime, because they are included in the .text
section of the executable, so they are always alive.
String literals are written in double quotes (""
). They can have the same escape sequences as char literals. Furthermore, a backslash (\
) at the end of the line can be used to remove the line break as well as all subsequent whitespace characters:
assert_eq!("Hello \
world", "Hello world");
Raw string literals
In raw string literals, escape sequences are ignored. Raw string literals are prefixed with an r
, and can be enclosed with an arbitrary number of number signs (#
). The number of number signs before and after the string must be equal:
r###"This is a "raw" string literal!"###
See also
Function pointer (fn
)
A type that points to a function:
fn foo(a: i32) -> i32 {
a * 3
}
let f: fn(i32) -> i32 = foo;
println!("{}", f(42));
Unlike closures, function pointers can't access their surrounding context, so it's often better to use Box<dyn Fn()>
or a generic impl Fn()
instead of fn()
.
Tuple (tuple
, unit
)
Main article: Tuple
A tuple is a fixed length sequence of values, which may or may not be different types.
let tuple: (bool, i32, &str) = (true, 42, "Hello");
A unit type is the empty tuple ()
. It is the type of statements and the implied type of functions that don't specify a return type. Since it has only one possible value, it is zero-sized:
fn foo() {}
fn bar() -> () {
let _: () = foo();
}
array
, slice
Main article: Arrays and slices
Arrays ([T; N]
) and slices ([T]
) are consecutive sequences of values of the same type. While arrays have a fixed size known at compile time, slices are dynamically sized and can only be used behind a reference or pointer-like type:
let array: [i32; 5] = [1, 1, 2, 3, 5];
let slice: &[i32] = &array[..];
Pointer, reference
See also: Reference
Never (!
)
Main article: Never