Rust примеры кода

Обновлено: 02.07.2024

Это вторая часть из цикла статей по переводу книги «Rust by Example». Первую часть можно прочитать здесь.

Содержание

1. Выражения

В Rust почти любой оператор (statement) так же является и выражением, это значит, что они могут вернуть какой-то результат. Такое поведение не всегда нужно, чтобы ничего не возвращать добавьте ; в конец.

Выражения в блоке могут использоваться в качестве r-values значений, а последнее будет назначено как l-value.
* Что такое Rvalue и Lvalue читайте здесь.

Но, если последнее выражение в блоке будет закачиваться точкой с запятой, результат будет равен пустому кортежу: ().

2. Операторы ветвления

Ветвление if-else является C-подобным. В отличие от C, логическое условие не должно быть заключено в круглые скобки, а после каждого условия необходимы фигурные скобки.

if-else так же является выражением; и, из-за типобезопасности Rust, все ветви должны возвращать значение одного типа.

3. Петли

Ключевое слово loop в Rust создает бесконечный цикл (петлю).

Оператор break позволяет выйти из петли в любое время, а continue пропускает оставшуюся часть итерации и начинает выполнение заново.

3.1 Вложенность и метки

Петли можно делать вложенными. В таких случаях они должны содержать метку 'label , а операторы break/continue писаться с этой меткой.

4. Цикл while

Тело цикла будет выполняться пока условие в while будет истинно.

Давайте напишем fizzbuzz используя цикл while .

5. Цикл for и функция range

Конструкцию for in можно использовать для перебора Iterator и ленивый генератор (подробнее позже). Функция range это один из наиболее распространенных итераторов. range(a, b) будет выдавать значения от a до b-1 изменяя шаг на единицу.

Давайте напишем fizzbuzz используя for вместо while .

6. Функции

Функции объявляются при помощи ключевого слова fn. Аргументы аннотируются типами, как и переменные; и, если функция возвращает значение, возвращаемый тип должен быть указан после стрелки ->.

Последнее выражение в теле функции будет использовано как возвращаемое значение или можно использовать оператор return для раннего возврата значения из функции, даже из внутреннего цикла или условного оператора.

Перепишем fizzbuzz используя функции!

6.1 Неиспользуемые функции


Обратите внимание, что в реальных программах, вы должны устранить «мертвый код». В этих примерах мы его используем для демонстрации.

Этот цикл статей является вольным переводом книги «Rust by Example», которую пишет Хорхе Апарисио на Github.

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

Содержание

1. Привет, мир!

Это код традиционной программы «Hello World»:

println! это макрос (мы рассмотрим их позже), который печатает текст в консоль.

Программа может быть сгенерирована с помощью компилятора Rust rustc:

rustc создаст бинарный файл «hello», который можно запустить:

2. Форматированный вывод

Макрос println! не только выводит в консоль, а также способен форматировать текст и сериализованные значения. Корректность проверяется во время компиляции.


Дополнительная информация о форматировании здесь: std​::fmt​

3. Литералы и операторы

Целые числа 1, с плавающей точкой 1.2, символы 'a', строки "abc" , логические true и значения пустого типа () могут быть выражены с помощью литералов.

Также целые числа можно выразить через шестнадцатеричное, восьмеричное или двоичное обозначение, используя один из префиксов: 0x, 0o или 0b.

В числовые литералы можно вставлять подчёркивания для читабельности, например, 1_000 такой же, как и 1000, а 0.000_001 такой же, как и 0.000001.

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

Доступные операторы и их приоритет похож на C-подобных языках.

4. Переменные

Значения (как и литералы) могут быть связаны с переменными, используя обозначение let.

4.1 Изменяемость
4.2 Области и видимость

Переменные имеют локальную область, и имеют видимость в блоке (блок представляет собой набор операторов, заключённых в фигурные скобки <>). Кроме того, допускается скрытие переменной.

4.3 Предварительное объявление

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


Компилятор запрещает использование неинициализированных переменных, так как это привело бы к непредсказуемым последствиям.

5. Типы

Rust обеспечивает безопасность с помощью статической проверки типов. Тип переменной может быть явно указан при её объявлении. Тем не менее, в большинстве случаев, компилятор сможет определить тип переменной из контекста, если это очевидно.

  • целые числа: i8 , i16 , i32 , i64 и int (размер зависит от платформы)
  • целые числа без знака: u8 , u16 , u32 , u64 и uint (размер зависит от платформы)
  • с плавающей точкой: f32 , f64
  • char значения Unicode: 'a', 'α' и '∞' (4 байта каждый)
  • bool true или false
  • кортежи ()
5.1 Приведение типов

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

5.2 Литералы

В числовых литералах тип может быть аннотирован, добавив тип в качестве суффикса, за исключением uint , использующей суффикс u и int , который использует суффикс i .

  • fun(&foo) используется, чтобы передать аргумент в функцию по ссылке, а не по значению fun(foo) .
  • std::mem::size_of_val является функцией, но вызывается с указанием полного пути. Код можно разделить на логические единицы, называемые модулями. Здесь функция size_of_val определена в модуле mem , а модуль mem определен в крэйте std .
5.3 Логический вывод

Логический вывод типов довольно умён. Тип добавляемой переменной используется как определитель типа для второй переменной. Вот продвинутый пример:

Отсутствует необходимость в аннотации типа переменной, компилятор счастлив как и программист!

5.4 Псевдонимы (алиасы)

Оператор type может быть использован, чтобы задать новое имя существующему типу. Тип должен быть в стиле CamelCase, либо компилятор выдаст предупреждение. Исключением из этого правила являются примитивные типы: uint , f32 и другие.


Основное применение псевдонимов это снижение количества кода, например, тип IoResult является псевдонимом типа Result<T, IoError> .

Читайте также: