Rust является языком со статической типизацией, а это значит, что для каждой переменной должен быть определен тип данных. Каждое значение в Rust имеет определенный тип данных. Тип данных определяет набор допустимых значений и устанавливает набор операций, применимых к этим значениям, и какой размер в памяти они могут занимать.
Типы данных бывают примитивными (или скалярными) и составными. Рассмотрим примитивные типы данных.
Ряд типов данных может хранить целые числа:
i8: хранит целое число со знаком и занимает в памяти 8 бит (диапазон значений от -128 до 127)
u8: хранит положительное целое число и занимает в памяти 8 бит (диапазон значений от 0 до 255)
i16: хранит целое число со знаком и занимает в памяти 16 бит
u16: хранит положительное целое число и занимает в памяти 16 бит
i32: хранит целое число со знаком и занимает в памяти 32 бита
u32: хранит положительное целое число и занимает в памяти 32 бита
i64: хранит целое число со знаком и занимает в памяти 64 бита
u64: хранит положительное целое число и занимает в памяти 64 бита
i128: хранит целое число со знаком и занимает в памяти 128 бит
u128: хранит положительное целое число и занимает в памяти 128 бит
isize: хранит целое число со знаком, размерность которого зависит от архитектуры компьютера - 64 бита на 64-битной архитектуре, и 32 бита на 32-битной архитектуре
usize: хранит положительное целое число, размерность которого зависит от архитектуры компьютера - 64 бита на 64-битной архитектуре, и 32 бита на 32-битной архитектуре
Как видно из списка типов у них логичные названия - сначала идет буква "i", если число может быть положительным и отрицательным, либо буква "u", если число может быть только положительным. Далее идет размерность числа в битах - какой размер оно занимает в памяти.
Примеры применения типов:
fn main(){ let a: i8 = 10; println!("a: {}", a); let b: u16 = 1000; println!("b: {}", b); let c: isize = 1234; println!("c: {}", c); }
Если тип не указан, то считается, что числовое значение имеет тип i32:
let a = 10; // переменная a имеет тип i32
Целые числа могут указываться в двоичном, восьмеричном, десятичном и шестнадцатеричном формате.
Двоичный формат - перед числом ставится 0b
:
let a = 0b0101; // 5 в десятичной системе
Восьмеричный формат - перед числом ставится 0o
:
let a = 0o11; // 9 в десятичной системе
Шестнадцатеричный формат - перед числом ставится 0x
:
let a = 0xA1; // 161 в десятичной системе
Дробные числа или точнее числа с плавающей точкой представлены двумя типами:
f32: хранит число с плавающей точкой, которое занимает в памяти 32 бита
f64: хранит число с плавающей точкой, которое занимает в памяти 64 бита
В качестве разделителя целой и дробной частей используется точка. Если тип явно не указан, то по умолчанию считается, что дробное значение имеет тип f64:
fn main(){ let a: f32 = 2.04; println!("a: {}", a); let b: f64 = 100.080973; println!("b: {}", b); let c = -45.78; // тип f64 println!("c: {}", c); }
Логический тип или bool может хранить одно из двух значений: true (истина) или false (ложь).
fn main(){ let a: bool = true; println!("a: {}", a); let b = false; println!("b: {}", b); }
Символьный тип или char может хранить отдельные символы Unicode. Каждый символ заключается в одинарные кавычки. В памяти он занимает 4 байта.
fn main(){ let a: char = 'a'; println!("a: {}", a); let b = 'b'; // тип char println!("b: {}", b); }
Строки не относятся к примитивным типам, тем не менее рассмотрим их, так как они довольно часто используются. Строка хранит набор символов в кодировке UTF-8, который заключается в двойные кавычки.
В качестве определителя типа применяется &str
fn main(){ let a: &str = "hello"; println!("a: {}", a); let b = "Rust"; // тип &str println!("b: {}", b); }