Байтовые представления общих типов.
Базовые типы
Основные типы встроены в ядро языка.
Безнаковые типы
Тип | Максимальное значение |
---|---|
u8 | 255 |
u16 | 65_535 |
u32 | 4_294_967_295 |
u64 | 18_446_744_073_709_551_615 |
u128 | 340_282_366_920_938_463_463_374_607_431_768_211_455 |
usize | В зависимости от размера указателя платформы, аналогично u16, u32 или u64. |
Типы со знаком
Тип | Максимальное значение |
---|---|
i8 | 127 |
i16 | 32_767 |
i32 | 2_147_483_647 |
i64 | 9_223_372_036_854_775_807 |
i128 | 170_141_183_460_469_231_731_687_303_715_884_105_727 |
isize | В зависимости от размера указателя платформы, аналогично i16, i32 или i64. |
Тип | Минимальное значение |
---|---|
i8 | -128 |
i16 | -32_768 |
i32 | -2_147_483_648 |
i64 | -9_223_372_036_854_775_808 |
i128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 |
isize | В зависимости от размера указателя платформы, аналогично i16, i32 или i64. |
Типы с плавающей точкой
Представление битовой выборки для f32:
Разъяснение:
f32 | S (1) | E (8) | F (23) | Значение |
---|---|---|---|---|
Нормализованное число | ± | 1 до 254 | любое | $±(1.F)_{2} * 2$$^E$$^-$$^1$$^2$$^7$ |
Денормализованное число | ± | 0 | ненулевой | $±(0.F){_2} * 2$$^-$$^1$$^2$$^6$ |
Нуль | ± | 0 | 0 | $±0$ |
Бесконечность | ± | 255 | 0 | $±∞$ |
Некорректное | ± | 255 | ненулевой | NaN |
Аналогично, для типов f64 это будет выглядеть как:
f64 | S (1) | E (11) | F (52) | Значение |
---|---|---|---|---|
Нормализованное число | ± | 1 до 2046 | любое | $±(1.F)_{2}$ * 2$^E$$^-$$^1$$^0$$^2$$^3$ |
Денормализованное число | ± | 0 | ненулевой | $±(0.F){_2} * 2$$^-$$^1$$^0$$^2$$^2$ |
Нуль | ± | 0 | 0 | $±0$ |
Бесконечность | ± | 2047 | 0 | $±∞$ |
Некорректное | ± | 2047 | ненулевой | NaN |
Преобразование типа через as
Преобразование | Результат | Комментарий |
---|---|---|
3.9_f32 as u8 | 3 | Усечение, сначала рассмотрите x.round(). |
314_f32 as u8 | 255 | Получает ближайшее доступное число. |
f32::INFINITY as u8 | 255 | То же самое относится к БЕСКОНЕЧНОСТИ как к действительно большому числу. |
f32::NAN as u8 | 0 | - |
_314 as u8 | 58 | Усечение избыточных битов. |
_200 as i8 | 56 | - |
_257 as i8 | -1 | - |
Арифметические подводные камни
Преобразование | Результат | Комментарий |
---|---|---|
200_u8 / 0_u8 | Ошибка компилятора | - |
200_u8 / _0 | Паника | Регулярная математика может паниковать, деление на ноль. |
200_u8 + 200_u8 | Ошибка компилятора | - |
200_u8 + _200 | Паника | В режиме отладки используйте проверку, вместо _. |
200_u8 + _200 | 144 | В режиме компиляции это приведет к переполнению. |
1_u8 / 2_u8 | 0 | Другие целочисленные деления усекаются. |
0.8_f32 + 0.1_f32 | 0.90000004 | - |
1.0_f32 / 0.0_f32 | f32::INFINITY | - |
0.0_f32 / 0.0_f32 | f32::NAN | - |
x < f32::NAN | false | NAN всегда возвращают значение false. |
x > f32::NAN | false | - |
f32::NAN == f32::NAN | false | - |
Выражение _100 означает все, что может содержать значение 100, например, 100_i32, но является непрозрачным для компилятора.
Текстовые типы
Базовые:
Тип | Комментарий |
---|---|
char | Всегда 4 байта и содержит только одно значение Юникода. |
str | Массив u8 неизвестной длины, содержащий символы в кодировке UTF-8. |
Применение:
Символы | Комментарий |
---|---|
let c = ‘a’; | Симвод юникода. |
let c = ’❤‘; | Может содержать любые символы Юникода. |
let c = ‘❤️’; | Но не всегда. Данный эмодзи представляет собой два символа (см. Кодирование) и не может быть в ‘c’. |
c = 0xffff_ffff; | Кроме того, символы не могут содержать произвольные битовые комбинации. |
Строки | Комментарий |
---|---|
let s = “a”; | Обычно str никогда не используется непосредственно, используется как &str. |
let s = “❤❤️”; | Может содержать произвольный текст, имеет переменную длину в ‘с’, трудно индексировать. |
Кодирование let t = “I ❤️ Rust”; let t = “I ❤️ Rust”;
Вариант | Представление в памяти | Примечание |
---|---|---|
s.as_bytes() | 49 20 e2 9d a4 20 52 75 73 74 | Обратите внимание, как ❤️, имея кодировку Юникода (U+2764), представляется как 64 27 00 00 внутри символа, и получил кодировку UTF-8 до e2 9d a4 в str. |
s.chars() | 49 00 00 00 20 00 00 00 64 27 00 00 20 00 00 00 52 00 00 00 75 00 00 00 73 00 … | Результат собирается в массив и передается в байты. |
t.as_bytes() | 49 20 e2 9d a4 ef b8 8f 20 52 75 73 74 | Также наблюдайте, как эмодзи красное ❤️, представляет собой комбинацию ❤️ и селектора вариантов U+FE0F, таким образом, ‘t’ имеет более высокое количество символов, чем ‘s’. |
t.chars() | 49 00 00 00 20 00 00 00 64 27 00 00 0f fe 01 00 20 00 00 00 52 00 00 00 75 00 … | Результат собирается в массив и передается в байты. |
Пользовательские типы
Основные типы, определяемые пользователем. Актуальное представление объекта.
Следует также отметить, что два типа A(X, Y) и B(X, Y) с точно такими же полями, могут иметь различную структуру; transmute() не гарантирует расположение.
Ссылки и указатели
Ссылки обеспечивают безопасный доступ к памяти, необработанные указатели это небезопасный доступ. Соответствующие мутабельные типы имеют идентичное расположение данных.
Должна быть задана допустимая величина ‘T’, и любая такая переменная должна существовать по крайней мере ‘а.
Метаданные указателя
Многие типы ссылок и указателей могут содержать дополнительное поле, метаданные указателей. Это может быть длина элемента или информация о объекте или указатель на таблицу vtable. Указатели с метаданными называются жирными, иначе тонкими.
Нет метаданных. (указатель тонкий).
Если T является структурой, такой как S {x: [u8]} метаданные поля len является числом. размер контента.
Регулярная ссылка среза (т.е. ссылочный тип среза [T]) часто рассматривается как &[T].
Ссылка на строковый фрагмент (т. е. ссылочный тип строкового типа str), причем метаданные len является длиной среза.
Метаданные указывают на таблицу vtable, где Drop::drop(), Trait::f(), … являются указателями на их соответствующий impl для Т.
Замыкания
Функции с автоматически управляемым захватом блоков данных. Например, если у вас:
let y = ...;
let z = ...;
with_closure(move |x| x + y.f() + z); // y и z перемещаются в функцию замыкания (типа C1)
with_closure( |x| x + y.f() + z); // y и z используются в функции замыкания (типа C2)
Немного упрощенная функция, это замыкание, является удобной для записи «мини-функцией», которая принимает параметры, но также имеет некоторые локальные переменные для выполнения своей работы. Этот тип (содержит нужные локальные переменные) в функции. «Захват переменных» - это модный способ сказать, что замыкание удерживает локальные переменные, либо по перемещенному значению, либо по указателю.
Генерируемые анонимные замыкания типов C1 и C2, переданные в with_closure(), будут выглядеть следующим образом:
Также создает анонимные функции, такие как f$_c$$_1$ (C1, X) или f$_c$$_2$ (& C2, X). Подробности зависят от того, какие FnOnce, FnMut, Fn… поддерживается на основе свойств используемых типов.
Типы переменных стандартной библиотеки
Стандартная библиотека rust объединяет вышеперечисленные примитивные типы c другими типами с особой семантикой, например:
Волшебный тип, допускающий совмещенную мутабельность.
Позволяет T’s перемещаться внутрь и наружу.
Также поддерживают динамическое заимствование T. Cell работает с Send, но не с Sync.
Запрещает T::drop() быть вызванным.
Этот тип аналогично.
Тег может быть опущен для определенных T, например NonNull.
Либо некоторая ошибка E, либо значение T.
Неинициализированная память или некоторые Т. Это легальный способ работы с неинициализированными данными.
Хранение коллекций
Для некоторых T стек-прокси может нести метаданные (например, Box<[T]>).
Вектор массива значений одного типа.
Элементы head и tail имеют значение null или указывают на узлы на куче. Каждый узел может указывать на свой предыдущий и следующий узел.
Заголовок индекса выбирает массив в качестве кольцевого буфера. Это означает, что содержимое может быть несмежным и пустым посередине, как показано выше.
Другие коллекции
Сохраняет ключи и значения в куче в соответствии с хеш-значением. HashSet идентичен HashMap, просто типа V нет. Представление кучи значительно упрощено.
В куче сохранен массив с 2N элементами на слой. Каждый Т может иметь 2 нижестоящих элемента в слое ниже. Каждый Т выше своего
ребенка.
Другие строки
Обратите внимание, чем строка отличается от &str и &[char].
NUL-окончание, но без NUL в середине.
Инкапсулирует, как работает операционная система представляя строки (например, WTF-8 в Windows).
Инкапсулирует, как работает операционная система представляя пути.
Совместное владение
Если тип не содержит Cell for T, то это часто комбинируется с одним из типов Cell (тип для примера), чтобы обеспечить общую фактическую мутабельность.
Совместное владение T в одном потоке. Для разрешения мутации требуется вложенное значение или ссылка на него. Это не передача и не синхронизация.
То же самое, но разрешить совместное использование между потоками, если они содержат T, это передача или синхронизация.
Внутренние поля зависят от платформы. Должны удерживается в Arc для разделения между разъединенными потоками, или через scope() для потоков с областью действия.