Primitive types

From Rust Community Wiki
(Redirected from Literal)
Jump to navigation Jump to search

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[edit | edit source]

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 PartialEqThis links to official Rust documentation trait, but not EqThis links to official Rust documentation.

Type Size Minimum real number Maximum real number Precision
Unsigned integers u8This links to official Rust documentation 1 byte 0 28 – 1 = 255 whole numbers
u16This links to official Rust documentation 2 bytes 0 216 – 1 = 65,535
u32This links to official Rust documentation 4 bytes 0 232 – 1 = 4,294,967,295
u64This links to official Rust documentation 8 bytes 0 264 – 1 ≈ 1.845 × 1019
u128This links to official Rust documentation 16 bytes 0 2128 – 1 ≈ 3.403 × 1038
usizeThis links to official Rust documentation Same as a pointer 0 Platform dependent
Signed integers i8This links to official Rust documentation 1 byte –27 = –128 27 – 1 = 127
i16This links to official Rust documentation 2 bytes –215 = –32,768 215 – 1 = 32,767
i32This links to official Rust documentation 4 bytes –231 = –2,147,483,648 231 – 1 = 2,147,483,647
i64This links to official Rust documentation 8 bytes –263 ≈ –9.223 × 1018 263 – 1 ≈ 9.223 × 1018
i128This links to official Rust documentation 16 bytes –2127 ≈ –1.701 × 1038 2127 – 1 ≈ 1.701 × 1038
isizeThis links to official Rust documentation Same as a pointer Platform dependent Platform dependent
Floating-point numbers f32This links to official Rust documentation 4 bytes –(2 – 2–23) × 2127 ≈ –3.403 × 1038 (2 – 2–23) × 2127 ≈ 3.403 × 1038 6 to 9 significant decimal digits
f64This links to official Rust documentation 8 bytes –(2 – 2–52) × 21023 ≈ –1.798 × 10308 (2 – 2–52) × 21023 ≈ 1.798 × 10308 15 to 17 significant decimal digits

Number literals[edit | edit source]

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.

boolThis links to official Rust documentation[edit | edit source]

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[edit | edit source]

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.

charThis links to official Rust documentation[edit | edit source]

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 chars aren't visible characters, and what looks like a single character, can consist of multiple chars.

char literals[edit | edit source]

char literals are chars 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}' == 'ḇ'

strThis links to official Rust documentation[edit | edit source]

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, chars in a string can't be indexed in constant time. Furthermore, the str::len()This links to official Rust documentation method returns the length in bytes, not in characters.

String literals[edit | edit source]

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[edit | edit source]

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[edit | edit source]

Function pointer (fnThis links to official Rust documentation)[edit | edit source]

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 (tupleThis links to official Rust documentation, unitThis links to official Rust documentation)[edit | edit source]

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();
}

arrayThis links to official Rust documentation, sliceThis links to official Rust documentation[edit | edit source]

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[edit | edit source]

See also: Reference

Never (!)[edit | edit source]

Main article: Never