Треки
/
Rust
Rust
/
Салабус
/
Цілі числа
Ці

Цілі числа у Rust

1 вправа

Про концепцію Цілі числа

Цілі числа - це числа без дробової або десяткової частини. У машині вони представлені як набір двійкових бітів.

Цілі числа можуть бути знаковими або беззнаковими. Знаковість означає, що один із бітів числа зарезервовано для позначення того, чи є число відʼємним.

Усі цілі числа мають розрядність, тобто просто кількість бітів, з яких складається число. Від цього залежить максимальне значення, яке може представити той чи інший цілий тип.

Наприклад, один із найпоширеніших цілих типів - u8: беззнакове 8-бітове ціле число. Цей тип можна впізнати як один байт. Його мінімальне значення - 0, а максимальне - 255.

У Rust є 12 примітивних цілих типів, розділених за розрядністю та знаковістю:

Беззнакові Знакові
u8 i8
u16 i16
u32 i32
u64 i64
u128 i128
usize isize

Розрядність цілого числа завжди вказує число після u або i. usize та isize особливі: вони мають ту саму розрядність, що й вказівник на цільовій машині. Це означає, що на 64-бітній архітектурі usize та isize завширшки 64 біти, а на 32-бітній - 32 біти.

Що використовувати?

Загалом, якщо треба просто представити якесь число, варто використати i32: 32 біти дають достатньо широкий діапазон, тож переповнення відносно малоймовірне, а знакові числа мають менше несподіванок, ніж беззнакові. i32 відповідає long у C або int у Java. Якщо використати числовий літерал і явно не вказати тип, він типово матиме тип i32.

Якщо працюємо з двійковими даними, найпростіше працювати з байтами: &[u8] або Vec<u8>.

Rust використовує usize для розміру та індексування колекцій. Це тому, що компʼютер теоретично може адресувати лише usize::MAX байтів памʼяті, тож більші колекції в памʼяті неможливі. Тому usize може стати в пригоді, якщо доводиться багато працювати з колекціями.

Якщо дані не вміщуються в 32-бітове ціле число, варто перейти до 64- або 128-бітового. Якщо дані не вміщуються і в 128-бітове ціле число, можна скористатися типом великих цілих чисел, наприклад тим, який надає num-bigint.

16-бітові цілі числа не дуже поширені, але можуть стати в пригоді для певних мікроконтролерів.

Якщо відомо, що в застосунку не буває коректних відʼємних значень, краще використати беззнакове ціле число, а не знакове. Лічба - гарний приклад цього.

Перетворення між цілими числами

У Rust немає неявних числових перетворень. Якщо потрібно привести один цілий тип до іншого, є дві основні стратегії: ключове слово as і трейти From та TryFrom.

Використання ключового слова as просте: expr as Type. Однак є низка застережень і тонкощів, які слід памʼятати, використовуючи приведення за допомогою as.

Приведення на основі трейтів трохи складніше, але безпечніше: трейти перетворення реалізовано лише там, де це безпечно. Наприклад, i32 реалізує From<u8>, From<u16>, From<i8> і From<i16>: будь-яке значення, яке можна представити будь-яким із цих типів, гарантовано можна представити й в i32. Його можна використати як i32::from(expr) або expr.into(), де expr має один із цих типів. i32 також реалізує TryFrom<u32>, TryFrom<u64>, TryFrom<u128>, TryFrom<usize>, TryFrom<i64>, TryFrom<i128> і TryFrom<isize>. Ці перетворення явно або вдаються, або спричиняють переповнення, залежно від значення. Щоб скористатися ними, потрібно імпортувати трейти std::convert::TryFrom або std::convert::TryInto за потреби, а потім використати i32::try_from(expr) або expr.try_into(), де expr має відповідний тип.

Приведення на основі трейтів загалом краще за приведення через as, особливо коли переходимо від ширшого типу до вужчого. Приведення на основі трейтів несуттєво дорожче за приведення через as: використовувати as заради швидкодії не варто, хіба що в надзвичайно гарячому циклі.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці