Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Примитивные типы данных

В языке Rust имеются такие примитивные типы данных.

Целочисленные типы

РазмерЗнаковыйБеззнаковый
8 битi8u8
16 битi16u16
32 битаi32u32
64 битаi64u64
128 битi128u128
Платформозависимый
(равный размеру указателя)
isizeusize

Если мы объявляем переменную без указания типа и инициализируем её целым числом, то по умолчанию используется тип i32. Если же мы инициализируем переменную числом с плавающей запятой, то по умолчанию используется тип f64.

#![allow(unused)]
fn main() {
let a = 5;   // i32
let b = 5.0; // f64
}

Тип числа можно указывать как явно, так и при помощи суффикса к инициализирующему значению:

#![allow(unused)]
fn main() {
let a: u8 = 5;
let b = 5u8;

let c: f32 = 5.0;
let d = 5.0f32;

let e: u128 = 1;
let f = 1u128;
}

Числа с плавающей запятой

Для представления чисел с плавающей запятой в Rust имеется два типа: f32 и f64. Соответственно, их размер 32 и 64 бита.

Оба типа реализуют стандарт IEEE-754, то есть значения типов f32 и f64 могут хранить как вещественные числа, так и “бесконечность” и “не число”.

#![allow(unused)]
fn main() {
let a: f32 = -1.0; // 1.0
let b = 5.0f32;    // 5.0
let c = a + b;     // 4.0
let d = 1.0 / 0.0; // inf
let e = a.sqrt();  // NaN
}

bool

Булевый тип в Rust ровно такой, каким его можно ожидать: может хранить либо true, либо false.

#![allow(unused)]
fn main() {
let a: bool = true;
let b = false;
}

Значение типа bool занимает в оперативной памяти 1 байт.

Символы

Для хранения отдельных текстовых символов используется тип char. Фактически это 4-байтное число, хранящее код символа в таблице Unicode.

Rust позволяет указать символ в исходном коде программы, как текстовый знак, взятый в одинарные кавычки.

#![allow(unused)]
fn main() {
let a = 'a';
let smile = '☺';
let book = '本';
}

Unit

Тип Unit — аналог типа void в C, Java и других им подобных языках. Как правило, он используется для обозначения типа результата в функциях, которые не возвращают какое-либо значение.

Хоть тип и называется “Unit”, в коде он обозначается как () .

Принципиальное отличие типа Unit, являющегося множеством-синглтон, от типа void, который представляет пустое множество, заключается в том, что у типа Unit есть одно единственное значение —(). Мы можем даже создать переменную типа Unit и присвоить ей () .

#![allow(unused)]
fn main() {
let a: () = ();
}

Tip

Чем не подходит void? Тип Unit появился в языках, которые испытали на себе влияние функционального программирования. Дело в том, что в функциональном программировании функция рассматривается, в первую очередь, как математическая функция, т.е. отображение значения из множества аргументов в значение из множества результатов. Здесь и появляется фундаментальная проблема типа void: это пустое множество, в котором нет значений. Это сильно усложняет моделирование системы типов для таких важных в функциональном программировании операций, как композиция функций.

В чисто функциональном языке Haskell даже имеется специальная функция absurd, которая принимает аргумент типа Void и возвращает некое значение.

absurd :: Void -> a

Какое это значение и какого оно типа — не важно, так как эту функцию невозможно вызвать, ведь для её вызова необходим элемент из пустого множества Void, а такой не существует.

Never type

Еще один интересный тип, обусловленный особенностями системы типов данных в языках, испытавших воздействие функционального программирования, — never type.

В коде этот тип обозначается как !

Этот тип практически никогда не указывается явно и даже не наблюдается в коде. Более того, если не знать о его наличии, то можно годами писать на Rust и даже не подозревать о его существовании.

На данном этапе мы пока что не сможем разобраться с этим типом. Скажем только, что компилятор использует этот тип для выражений, которые никогда не возвращают значение в вызывающий код. Например, для функции выхода из программы.

Мы подробнее рассмотрим never type в главе Функции.

Приведение типов

Для того чтобы преобразовать один тип данных в другой, используется оператор as.

Синтаксис:

значение as Тип

Пример:

fn main() {
    let a: i32 = 5;
    let b: i64 = a as i64;
    let c: i32 = b as i32;

    let d: f32 = 7.0;
    let e: i32 = d as i32;

    let f: bool = true;
    let g: i32 = f as i32; // 1
    let h = false as i32;  // 0

    let i = 'A' as i32; // 65
    let j = 66 as char; // B
}

Rust является языком со строгой типизацией, поэтому в нём отсутствуют неявные преобразования типов, как в C. Любое преобразование типов нужно указывать явно при помощи оператора as.