Rust io что это

Обновлено: 04.07.2024

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

В компании Evrone язык Rust применяется на многих проектах, и наши инженеры накопили большую экспертизу в этом направлении. В публикации мы расскажем об особенностях Rust.

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

Чем примечателен язык:

  • Сильная статическая типизация.
  • Отсутствие сборки мусора и возможность самостоятельно с помощью указателей контролировать место размещения данных в памяти.
  • Мощный встроенный статический анализатор кода, который позволяет избегать ошибок, связанных с управлением памятью и многопоточностью.
  • C-подобный синтаксис с лаконичными ключевыми словами.

Работу над Rust начал в 2006 году энтузиаст Грэйдон Хор. В 2009-м проектом заинтересовалась Mozilla, и уже спустя год был дан публичный анонс нового языка программирования.

Альфа-версия Rust появилась в 2012 году. Через год авторы браузерного движка Servo на базе этого языка сообщили, что их детище получило поддержку Samsung. Благодаря этому удалось портировать код движка на ARM-архитектуру.

Версия Rust 1.0 была представлена в мае 2015 года. В том же году язык занял третье место в опросе Stack Overflow о любимых инструментах разработчиков. Начиная с 2016 года Rust регулярно возглавляет этот список.

Преимущества:

  • Единый компилятор от разработчиков Rust со встроенным менеджером и сборщиком пакетов, системой тестов и генератором документации.
  • Безопасная работа с памятью, не допускающая ошибок сегментации.
  • Возможность применять абстракции, облегчающие ручное управление памятью.
  • Для многих ошибок во время компиляции приводятся варианты исправления, ошибки в шаблонах понятны и лаконичны.
  • Указатели можно использовать только в небезопасном коде, в безопасном коде применяются исключительно ссылки на гарантированно существующие объекты.
  • Хорошо совместим с Mac и Unix-подобными системами.
  • Отсутствие классов и наследования, что затрудняет написание кода в объектно ориентированной парадигме.
  • Очень строгий компилятор кода, иногда чересчур сильно контролирующий обращения к памяти.

Данный язык поддерживает основные парадигмы программирования: объектно ориентированное, параллельное, функциональное и процедурное. Rust универсален и подходит для решения различных задач: разработки операционных систем, программ общего назначения, веб-серверов и клиентов, систем мониторинга серверов, разработки инфраструктуры, приложений для мониторинга системы, блокчейн-сетей, игровых и браузерных движков.

Rust создавался в первую очередь как язык системного программирования. Он предоставляет достаточно возможностей для управления памятью и защиты от уязвимостей, чтобы стать востребованным инструментом для разработки операционных систем и ключевых приложений. Главная проблема языка — низкая поддержка со стороны производителей «железа», предпочитающих использовать для работы именно С/С++.

Успешные проекты:

  • Redox, Unix-подобная операционная система, базирующаяся на микроядре. Основная часть ПО для этой ОС также написана на Rust.
  • Servo, браузерный движок с поддержкой многопоточности.
  • Система микровиртуализации, созданная преимущественно под serverless окружения Firecracker.

Системы на базе распределенного реестра должны уметь быстро обрабатывать запросы внутри сети при минимальной нагрузке на устройство. Инструментарий С++ отлично справляется с этой задачей (именно на нем работают блокчейны Bitcoin и Ethereum), а посему разработка инфраструктуры с использованием Rust окажется еще эффективнее.

Успешные проекты:

    — альтернативный клиент Ethereum и Bitcoin. — гетерогенные блокчейн-сети.
  • Exonum, фреймворк для создания блокчейн-проектов.
  • MaidSafe, распределенная система хранения и обработки данных.
  • Solana, платформа для создания блокчейн-приложений.

Успешные проекты:

  • Dropbox, облачное хранилище.
  • OpenDNS, веб-сервис, позволяющий использовать общедоступные DNS-серверы.
  • Coursera, образовательный портал, основанный профессорами информатики Стэнфордского университета.

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

С++ почти 40 лет доминировал среди других языков, успел стать промышленным стандартом и по праву удерживает это звание по сей день. Rust стремительно развивается, дорабатывается и старается решать существенные недостатки С++ и других языков программирования.

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

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

Создание нового проекта

Для того чтобы создать новый проект:

Первая команда cargo new принимает название программы ( guessing_game ) как первый аргумент. --bin велит Cargo подготовить проект для написания программы (в отличие от библиотеки). Посмотрим, что у нас в конфигурационном файле проекта — Cargo.toml

Если сведения об авторе, которые Cargo получил из вашей системы, неправильные, исправьте конфигурационный файл и сохраните. По умолчанию в новом проекте содержится "Hello, world".
src/main.rs

Давайте соберем программу и запустим:

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

Обновление крейта до свежей версии

Когда вы хотите обновить крейт, Cargo предоставляет нам команду update, которая:

  • игнорирует Cargo.lock и выясняет последние версии зависимостей, которые удовлетворяют заданным вами требованиям в Cargo.toml.
  • если это удается, Cargo пишет эти номера версий обновленный зависимостей в Cargo.lock
    По умолчанию Cargo будет использовать версии > 0.3.0 и < 0.4.0 . Если авторы rand выпустят две новые версии, например, 0.3.15 и 0.4.0 , то вы увидите следующее при обновлении зависимостей ( cargo update ):

После этого вы заметите, что версия rand в Сargo.lock изменилась на 0.3.15 . Если же вы хотите использовать rand версии 0.4.0 или любой другой 0.4.x версии, то вы должны будете обновить Cargo.toml, чтобы он выглядел следующим образом:

В следующий раз, когда вы запустите команду cargo build , Cargo обновит индекс доступных крейтов и заново пересмотрит зависимости. Cargo позволяет очень легко подключать сторонние библиотеки, чем способствует повторному использованию кода (code reuse). При этом легко
писать новые крейты, используя уже имеющиеся как строительные блоки.

Храним значения в переменных

Теперь создадим место, где будет храниться пользовательский ввод:

Обратите внимание оператор let , который нужен для создания переменных (variables). Можно и так:

Код создает переменную с именем foo и привязывает ( bind ) к значению bar . В Rust по умолчанию переменные неизменяемые. Что сделать их изменяемыми, рядом с let до имени переменной добавьте mut .

Теперь вы знаете, что let mut guess создает изменяемую переменную guess . С правой стороны знака = находится значение, к которому "привяжется" guess — это результат вызова String::new , функции возвращающей новую строку. String — это строковый тип (подобный string в C++ и StringBuilder в Java), который может расти, содержит закодированный в UTF-8 текст. :: в ::new указывает на то, что new это ассоциированная функция (associated function) при типе String . Ассоциированная функция реализована над типом, в данном случае над String, а над конкретным экземпляром типа. Некоторые языки, например C++, называют такие функции статическими (static) методами. Функция new создает новый пустой экземпляр String . Вы увидите, что new реализована над многими типами, потому что используется для обозначения функции, которая создает новое значение какого-либо типа. Обобщим: let mut guess = String::new(); создала новую изменяемую переменную, которая "привязана" (bound) к новому пустому экземпляру String (пустой строке). Мы подключили функции для работы с IO посредством use std::io . Теперь вызовем ассоциированную функцию stdin :

Если бы мы не писали use std::io в начале программы, то мы могли бы записать обращение к этой функции в виде std::io::stdin . Функция stdin возвращает экземпляр std::io::Stdin , который является типом, который представляет собой указатель (handle) на стандартный поток ввода (standard input). Здесь им является пользовательская клавиатура. Следующая часть нашего кода, .read_line(&mut guess) , вызывает read_line на только что полученном указателе (handle) на stdin , чтобы считать ввод пользователя. Мы также посылаем единственный аргумент: &mut guess . read_line принимает от пользователя то, что приходит в stdin и помещает этот ввод в строку, поэтому принимает ссылку на строковую переменную. Этот строковой аргумент должен быть изменяемым, чтобы метод мог изменять значение этой строки, добавляя туда пользовательский ввод. & указывает на то, что данный аргумент ( &mut guess ) является ссылкой ( reference ), которая позволяет разным частям кода обращаться к одной области данных, не копируя значение из этой области данных много раз. Одной из сильных сторон Rust является то, что со ссылками легко (и при этом не повреждая память) обращаться. Пока что нам достаточно знать, что ссылки, как и переменные, по умолчанию являются неизменяемыми. Поэтому мы пишем &mut guess (создаем изменяемую ссылку), а не &guess (создаем неизменяемую ссылку).

Когда вы вызываете метод, используя синтаксис .foo() , бывает целесообразно перейти на новую строку, чтобы линия кода была не слишком длинной. Это облегчит чтение кода для других программистов.

читается несколько тяжелее.

Завершение игры при правильной догадке

Подведем последний штрих, добавив break для выхода из игры после выигрыша игрока:

Мы добавили break после команды печати You win! , так что теперь программа будет выходить из цикла, после того, как пользователь правильно отгадает число. Выход из цикла повлечет за собой завершение программы, ибо цикл является последней частью тела функции.

Rust: Знакомимся с языком на примере «Угадай-ки»

Давайте познакомимся с Rust, поработав над маленьким проектом! Мы покажем основные концепты Rust на реальном примере. Вы узнаете о let , match , методах, ассоциированных функциях, подключении сторонних библиотек и много о чем другом. Мы реализуем классическую задачу: игра “угадай-ка”.

  1. Программа генерирует случайное число от 1 до 100.
  2. После этого просит игрока ввести его догадку.
  3. После этого программа уведомляет игрока:
    • если он угадал число, то игра заканчивается
    • если нет:
      • пишет, меньше предложенное число чем загаданное или больше.
      • переходит к шагу 2.

Используем крейты для получения дополнительного функционала

Крейт — это всего лишь пакет кода на Rust. Мы с вами пишем исполняемый крейт (binary crate) — обычную программу в виде исполняемого (executable) бинарного файла. rand — библиотечный крейт (library crate), подобен .o и .so файлам в C — содержит функции, которые может подключить любой другой крейт. Cargo очень удобно использовать для установки сторонних крейтов. Для того чтобы начать использовать крейт rand , мы должны внести соответствующие изменения в Cargo.toml, чтобы он включал rand как зависимость (dependency). Внесем изменения в секцию [dependencies]

В файле Cargo.toml все что следует после заголовка секции продолжается до того, пока не начнется новая секция. Секция [dependencies] — это то место, где вы указываете Cargo крейты, от которых зависит код вашего проекта, и какие именно версии вам нужны. В данном случае мы указали, что нам для сборки проекта требуется крейт rand со спецификатором версии 0.3.14 . Cargo понимает модель семантического назначения версий (Semantic Versioning), который является одним из стандартов присваивания имен разным версиям программ. Число 0.3.14 (на самом деле это краткая форма записи ^0.3.14 ) означает, что подходит любая версия, у которого открытый (public) API совместим с версией 0.3.14. Соберем, но уже с новой зависимостью:

Предлагайте ваши догадки несколько раз

Ключевое слово loop позволяет нам создать бесконечный цикл. Добавим:

Как вы можете видеть, мы поместили все в цикл. Запустим:

Введение quit завершает игру, впрочем, как и любой друго не-числовой ввод. Однако это не очень удобно: мы хотим, чтобы игра завершалась, когда пользователь угадывает число.

Сравниваем догадку с секретным числом

После того как мы сгенерировали случайное число и получили догадку от пользователя, мы можем сравнить их. Внесем изменения в src/main.rs

Первым незнакомым элементом здесь является еще одно использование оператора use , который привносит в область видимости тип std::cmp::Ordering из std. Ordering — еще одно перечисление, оно подобно Result , но имеет другие варианты:

  • Less
  • Greater
  • Equal
    Это три возможных результата, которые мы можем получить при сравнении двух чисел. Также мы добавили код, использующий тип Ordering :

Метод cmp сравнивает два числа, он может быть вызван применительно к любым двум сущностям, которые сравнимы между собой. Он получает ссылку на то, с чем вы хотите сравнить данный элемент: в данном случае сравнивается guess и secret_number . cmp возвращает вариант Ordering (мы внесли его в область видимости ранее посредством оператора use ). Мы также используем сопоставление match для того, чтобы, в зависимости от результатов сравнения, решить, как следует поступить далее. Сопоставление match состоит из веток ( arm s). Ветка состоит из шаблона и кода, который должен быть выполнен, если сопоставляемое выражение соответствует шаблону ветки. Rust последовательно сопоставляет выражение c шаблонами в ветках match , и после того, как будет найдено соответствие, код справа от подошедшего шаблона исполняется. Давай рассмотрим пример возможного взаимодействия с программой. Скажем, пользователь предложил число 50 как догадку, а секретным (задуманным) числом является 38. Когда код сравнивает 50 и 38, cmp метод возвращает Ordering::Greater , потому что 50 > 38. Ordering::Greater — это значение, которое принимает match . match смотрит на шаблон первой ветки, Ordering::Less , но значение Ordering::Greater не сопоставимо (в данном случае потому что не равно) c Ordering::Less , поэтому игнорирует код в этой ветке и переходит к сопоставлению со следующими шаблонами. Шаблон следующей ветки, Ordering::Greater сопоставим с Ordering::Greater (который мы передали match ). Соответствующий код в данной ветке исполняется и печатает Too big! . Выражение match завершает сопоставление выражения с шаблонами, потому что соответствие уже найдено. Однако данный код содержит ошибку, поэтому не может быть скомпилирован:

В ошибке говорится, что здесь сравниваются несопоставимые типы. Rust — это язык со строгой статической типизацией, имеющий, однако, выведение типов. Когда мы написали let guess = String::new() , Rust смог вывести, что переменная guess должна иметь тип String , и не заставил нас писать этот тип вручную. С другой стороны, secret_number — числовая переменная. Переменные некоторых типов могут принимать значения от 1 до 100. Сюда относятся следующие типы:

  • i32 — 32-битное число (может принимать отрицательные значения)
  • u32 — 32-битное число (принимает только неотрицательные целые значения)
  • i64 — 64-битное число (может принимать отрицательные значения)
    и другие. Rust по умолчанию использует тип i32 , и переменная secret_number имеет данный тип (если только мы не укажем другой тип вручную, что будет указанием компилятору, что мы хотим, чтобы он сделал secret_number переменной другого, указанного нами типа). Причиной ошибки является то, что Rust не может сравнить переменную строкового типа с переменной числового типа. В конечном итоге мы хотим преобразовать переменную типа String , которую программа считывает со стандартного потока ввода, в число, чтобы мы могли сравнить догадку пользователя с загаданным числом. Мы может достичь этого добавлением следующего кода в main :

Здесь был добавлен код:

Отлично! Несмотря на то что перед догадкой были введены пробелы, программа выяснила, что пользователь предложил 76. Запустите программу несколько раз и удостоверьтесь, что программа по-разному реагирует на разные догадки пользователя:

  • угадайте число
  • предложите большее число
  • предложите меньшее число
    Большая часть игры уже готова, однако пользователь может вводить только одну догадку. Исправим это, добавив цикл.

Обработка завершения с ошибкой (используем Result )

read_line не только считывает строку, но и возвращает значение, здесь это значение типа io::Result . Rust имеет несколько типов, называющихся Result в разных библиотечных модулях.

Компилятор уведомляет нас, что мы не использовали возвращенное значение Result , указывая на то, что программа не обработала возможную ошибку. Чтобы подавить предупреждение, нужно написать код обработки ошибки, но мы используем expect , ибо хотим увидеть, как программа завершается с ошибкой.

Обработка неправильного ввода

Давайте сделаем так, чтобы программа игнорировала неправильный ввод и позволяла пользователю продолжать игру, вместо того чтобы аварийно завершаться. Для этого изменим то место, где строка преобразовывается в число:

Переход от expect к match меняет поведение программы. Теперь программа не завершается аварийно, а обрабатывает ошибку. Если метод parse может успешно преобразовать строку в число, то он возвращает Ok и сопоставление match , в свою очередь, возвращает извлеченное из Ok число ( num ), которое parse в этот Ok завернул. После этого данное число окажется присвоенным новой переменной guess . Если же метод parse не может успешно преобразовать строку в число, то он возвращает вариант Err , который содержит в себе сведения о произошедшей ошибке. Значение Err не может быть успешно сопоставлено с шаблоном Ok(num) в первой ветке выражения match , но оно успешно сопоставляется с шаблоном Err(_) во второй ветке. _ является шаблоном, который успешно сопоставляется с любым выражением, в нашем примере Err(_) будет успешно сопоставлен с любой ошибкой внутри варианта Err . После успешного сопоставления будет выполнен код во второй ветке match — continue , что приведет к переходу к следующей итерации цикла. Теперь программа работает должным образом:

Плагин Rust:IO Clans

Это аддон создан для Rust:IO. Для того, чтобы использовать все возможности этого плагина, необходимо сначала установить Rust:IO!

Rust:IO Clans предоставляет игрокам в пользование довольно многофункциональную систеу кланов. Он позволяет:


Перевод

В директории config/Clans.json находится конфигурационный файл, который содержит все переводимые строки. Вам нужно просто отредактировать правую сторону перевода, но всегда оставляйте %PLACEHOLDERS% нетронутыми и непереведёнными

Конфигурирование

В директории config/Clans.json также есть несколько переменных для настройки плагина:

  • addClanMatesAsFriendsопределяет, добавляются ли товарищи по клану автоматически друг к другу в список друзей Rust:IO (по умолчанию: true).
  • limitопределяет максимальное количество членов клана и модераторов (по умолчанию: -1 = no limit)

API плагина

Данный плагин имеет простой API для использования другими плагинами:

  • GetClan(tag:string):JObject
    Возвращает JObject (ссылку на Newtonsoft.Json.dll), представляющий клан с использованием специализированного тега, или null, если такого клана нет. JObject содержит следующие параметры: tag:string, description:string, owner:string, moderators:JArray, members:JArray, invited:JArray. Все члены клана представлены по их SteamID в виде строки.
  • GetClanOf(player:ulong|string|BasePlayer):string
    Возвращает тег клана, к которому принадлежит игрок, илиnull, если игрок не является членом клана.
  • GetAllClans():JArray
    Возвращает все теги клана в виде массива.

Плагин также поддерживает следующие процедуры-перехватчики (отменить их действие нельзя):

Обработка догадки

Первая часть нашей программы будет просить пользователя ввести его догадку, обрабатывать его ввод и проверять, что он корректен (valid). Для начала давайте дадим пользователю ввести его догадку: Здесь и далее все изменения вносятся в src/main.rs :

Код несет в себе много информации, так что рассмотрим его постепенно. Чтобы получить введенную догадку от пользователя и вывести ее в stdout, мы должны внести io библиотеку в глобальную область видимости (scope). io является частью стандартной библиотеки (здесь и далее std ):

По умолчанию Rust привносит в область видимости программы только несколько типов ( prelude ). Если в prelude нет нужного вам типа, то следует внести его в область видимости вручную написанием оператора use . Использование std::io дает нам множество функций для работы с вводом-выводом (IO), включая возможность считывать ввод пользователя. Функция main (как и в C и в C++) является точкой входа (entry point) в программу.

fn позволяет объявить новую функцию, () указывает на то, что функция не принимает параметров, < предваряет тело функции. println! — макрос ( macro ), который выводит строку на консоль:

Проверка первой части

Программа запросила число, мы ввели, программа вывела это число — все работает. Идем дальше.

Генерирование секретного числа

Задумаем число (от 1 до 100), которое пользователь будет пытаться угадать. Это должно быть случайное число, чтобы в игру можно быть играть больше одного раза. У Rust в std (стандартной библиотеке) нет модуля для работы со случайными числами, поэтому используем стороннюю библиотеку (крейт (crate) в терминах Rust) rand .

Rust io что это

Эта публикация удалена, так как она нарушает рекомендации по поведению и контенту в Steam. Её можете видеть только вы. Если вы уверены, что публикацию удалили по ошибке, свяжитесь со службой поддержки Steam.

Этот предмет несовместим с Rust. Пожалуйста, прочитайте справочную статью, почему этот предмет может не работать в Rust.

Этот предмет виден только вам, администраторам и тем, кто будет отмечен как создатель.

В результатах поиска этот предмет сможете видеть только вы, ваши друзья и администраторы.


Что такое Rust ? Я расскажу вам про него все !) Это Горелка Жопы)1)


1


1,068 уникальных посетителей
2 добавили в избранное






  • 1 Это горящая игра , у тебя на 10 часов игры горит пукан от ♥♥♥♥♥♥♥♥♥♥♥♥ бомжей с камушками тебя ♥♥♥♥♥♥♥♥ сзади , не дают развиться , в соло не вариант ♥♥♥♥♥♥♥♥♥♥♥♥♥♥ в раст , лучше дуо )
    2. сразу скажу при игре в раст берите воду ) так как у вас будет жечь пукан ))))
    3. После постройки кибитки вас ♥♥♥♥♥♥♥♥ бомжи в дверь . Что делать? хммм пойду отойду за чаем )) Вернувшись L: вас рейданули ) ♥♥♥♥♥♥♥♥а вам .
    Вся игра построена на горящих школьниках , макросниках, бомжами , и добыча ♥♥♥♥♥♥♥♥♥♥♥♥ ресов камнем ♥♥♥♥♥♥♥♥♥♥♥♥♥♥
    Я думаю эта инфа полезна)

Привет.. После долгих мучений игры мы с кланом развились и начали ♥♥♥♥♥♥♥♥♥♥ всех в попу :)
Итоги: В целом игра не плохая, так как у меня 160 часов, скажу так, да я не задрот, но и оскать игру не стану, так как мне она нравится, как не крути все равно будешь в раст играть, до последнего!)
Всем спс, ставим лайки и ждите новое руководство 🔴😉

Игра стоит своих денег, за 100 часов игры ты бомбишь, и играешь все равно, учишься тактике, стрельба ууу самое то в этой игре🔶(^o^) без ума не выловить рыбу из пруда :), целебные чайки УФФ мне они нравятся так как они как буст)
Если вы купите игру, то только по скидке советую 😉☕

Генерирование случайного числа

Перейдем к использованию rand , для этого обновим src/main.rs

Мы добавили extern crate rand; , что указывает rustc на то, что нужно подключить стороннюю библиотеку. Это также подобно use rand , ибо теперь у нас появилась возможность вызывать функции из rand посредством написания rand:: . Также мы добавили use rand::Rng . Rng — типаж, который определяет методы, которые будут реализованы генераторами случайных чисел. Это типаж должен быть в области видимости, чтобы мы могли использовать его методы. Также мы добавили две строчки в середине. Функция rand::thread_rng возвратит генератор случайных чисел, который является локальным для текущего потока (thread), будучи предварительно инициализированным (seeded) операционной системой. Далее мы вызываем gen_range у генератора. Этот метод определен в типаже Rng , который мы предварительно внесли в область видимости оператором use rand::Rng . gen_range принимает два числа и возвращает случайное число, которое находится между ними. Диапазон включает в себя нижнюю границу и не включает верхнюю, поэтому мы должны указать числа 1 и 101 , чтобы получить число от 1 до 100. Чтобы ознакомиться со всеми возможностями крейта, нужно прочитать его документацию. Еще одной возможностью Cargo является то, что вы можете "собрать" документацию, вызвав команду cargo doc --open , после чего документация будет открыта в браузере (после сборки). Если вас интересует другая функциональность крейта rand , то выберите пункт rand в панели слева. Вторая строка, которую мы добавили, печатает секретное число. Пока что оставим это так, это удобно для проверки работы программы, в финальной версии программы ее уже не будет. Запустим пару раз:

Программа должна каждый раз выводить разные случайные числа от 1 до 100.

Cargo.lock способствует сборке воспроизводимых (reproducible builds) программ

Cargo имеет средства, которые позволяют получать возобновляемые сборки, он будет использовать только те версии зависимостей, которые вы указали, до тех пор, пока вы не укажете другие версии зависимостей. Что будет, если появится крейт rand версии v0.3.15 , содержащий важное исправление (bug fix), и регрессию (regression), которая "ломает" ваш код? Для того чтобы решить эту проблему, используется файл Cargo.lock, который был создан при первом запуске cago build и теперь находится в корневой директории проекта. Когда вы собираете проект в первый раз, Cargo выясняет номера зависимостей, которые соответствуют заданным требованиям (в Cargo.toml) и записывает сведения о них в Cargo.lock. Когда вы собираете ваш проект во второй и последующий разы, Cargo видит, что Cargo.lock уже существует и использует версии, которые там указаны, а не выводит их заново, тратя время на анализ зависимостей. Это дает нам возможность получать воспроизводимые сборки. Другие словами, вам проект будет использовать крейт rand версии 0.3.14 , пока вы явно не произведете обновление.

Печать значений посредством println!

<> является "заполнителем" (placeholder), указывает на то, что в полученной строке будет значение соответствующей этому заполнителю переменной. Чтобы напечатать несколько значений, используйте несколько заполнителей: первый заполнитель ( <> ) соответствует первому выводимому значению, второй — второму и т.д. Например, так:

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