Основы Rust. Глава 1 — Знакомство с Rust

от автора

Rust – это язык программирования, разработанный Mozilla и поддерживаемый большим опенсорс сообществом. Начал его разрабатывать Graydon Hoare в 2006 году. Mozilla начало спонсировать проект в 2009 и впервые он был официально представлен в 2010 году. Работа над ним прошла через много итераций и завершилась 15 мая 2015 года, выпустив первую стабильную версию 1.0.0. Rust основан на ясных и твердых принципах. Он является системным языком программирования, и по возможностям идет вровень с C и C++. Rust такой же быстрый, как и C++, при этом более безопасный, так как запрещает использовать код, который может вызвать сбой программы из-за проблем с памятью. Кроме того, Rust имеет встроенные функциональные возможности, необходимые для параллельного выполнения на многоядерных машинах, а это делает параллельное программирование безопасным для памяти, не используя при этом сборки мусора, это единственный язык, который такое может предоставить. Rust также устраняет повреждения при совместном использование данных, через параллельный доступ, также известный, как “гонки данных”.

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

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

Mozilla является компанией, которая известная своей миссией разрабатывать инструменты для эволюции открытых стандартов в веб сфере, прежде всего через их ведущий браузер Firefox. Каждый браузер сегодня, включая Firefox, написан на C++, в Firefox примерно 12,900,992 строк кода, в Chrome – 4,490,488. Это позволяет программам быть быстрыми, но они также являются и небезопасными, поскольку в C и C++ разрешены манипуляции с памятью без проверки на валидность. Если код написан без должного внимания со стороны разработчика, то при выполнении программа падает, происходит утечка памяти, ошибки сегментации и могут произойти нулевые указатели. Некоторые из них могут привести к серьезным проблемам с безопасностью, которые хорошо известны в современных браузерах. Rust разрабатывался с нуля, чтобы избежать подобных проблем.

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

В Rust, для решения этой дилеммы, реализовано следующее:

  • Высокая безопасность благодаря своей сильной системы типов
  • Глубокое, но безопасное, управление низкоуровневыми ресурсами (как в C/C++) так, чтобы это работало как можно ближе к оборудованию

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

Rust достигает обе цели без сборщика мусора, который присутствует в большинстве современных языках, таких как Java, C#, Python, Ruby, Go. На самом деле, в Rust этого сборщика мусора пока и нет (один планируется появится). Rust- компилируемый язык: строгие правила безопасности осуществлены компилятором так, что они не вызывают издержки времени выполнения. В следствие чего, Rust может работать с минимальным временем выполнения, или даже не тратя время вовсе. Таким образом, его можно использовать в реальном времени или встроенным проектом, его также можно интегрировать с другими языками или проектами.

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

Троица Rust – безопасность, скорость и многозадачность

Rust- это не революционный язык с новыми передовыми функциями, но он включает много проверенных средств из старых языков, в широком масштабе улучшая дизайн C++ в вопросах безопасного программирования.

Разработчики создавали Rust с целью сделать его универсальным и языком мультипарадигмы. Как C++, он императивен, структурирован и объектно-ориентирован. Помимо этого, он перенял много из функциональных языков и также включает усовершенствованные методы для многозадачного программирования.

В Rust типизация переменных статична (поскольку Rust компилируемый) и сильна. Однако, в отличие от Java или C++, разработчику не нужно указывать типы для всего, так как компилятор Rust, во многих случаях, способен сам определить типы данных.

C и C++, как известно, имеют проблемы, которые приводят к аварийному завершению программы или утечки памяти, которые трудно отладить и решить. Подумайте о висячих указателях, переполнение буфера, нулевых указателях, отказе сегментации, гонки данных, и т.д. Компилятор Rust (именуемый rustc), очень умный и может обнаружить все эти проблемы при компиляции кода, таким образом, гарантируя безопасность памяти при выполнение. Это осуществляется компилятором, сохраняя полный контроль над памятью, без необходимости нагружать себя сборщиком мусора. Кроме того, эта безопасность также подразумевает намного меньше возможностей нарушить защиту.

Rust компилирует машинный код, как Go и Julia. Однако, в отличие от них, Rust не нуждается в сборщике мусора. В этом отношение, также отличается Java JVM и языки работающие на JVM от Scala и Clojure. Большинство других популярных современных языков, такие как .NET с C# и F#, JavaScript, Python, Ruby, Dart, нуждаются в виртуальной машине и сборщике мусора.

Как один из механизмов многозадачности, Rust перенял известную модель акторов из Erlang. Легковесные процессы называются потоками, которые выполняют работу параллельно. Они не разделяют память “кучи”, но передают данные через каналы, и гонки памяти устраняются с помощью системы типов. Эти примитивы упрощают работу программистам, используя всю мощь многоядерных процессоров.

Компилятор rustc полностью самодостаточен, он написан на Rust и может скомпилировать себя сам, используя предыдущую версию. В качестве бэкэнда, он использует компилятор LLVM и создает изначально выполняемый код, который работает невероятно быстро, потому что он компилирует в тот же низкоуровневый код, как и C++

Rust разрабатывался, чтобы быть таким же портативным, как и C++, и работать на разном оборудование и программных платформах. В настоящее время он работает на Linux, Mac OS X, Windows, FreeBSD, Android, и iOS. Он может запускать кода на C так же просто и легко, как если бы C запускал собственный код, и наоборот, C может также запускать код, написанный на Rust.

Сравнение с другими языками

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

Объектная ориентация в Rust не является настолько явной или продвинутой, как в объектно-ориентированных языках, таких как Java, C#, и Python, поскольку в нем нет классов. По сравнению с Go, Rust дает вам больше контроля над памятью и ресурсами, что позволяет вам писать код на более низком уровне. Go также работает со сборщиком мусора, и он не имеет универсальных шаблонов или механизмов для борьбы с гонками данных между его goroutines, использующимися в многозадачности. Julia фокусируется на числовой вычислительной производительности. Он работает с компилятором JIT и не дает вам такого низкоуровневого контроля, который предоставляет Rust.

Использование Rust

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

  • Клиентские приложения, такие как браузер
  • Низкая задержка, высокая производительность, в таких вещах, как драйвера устройств, игры и обработчик сигнала
  • Распределенные и параллельные системы, такие как серверные приложения
  • Системы реального времени, такие как ядро операционной системы
  • Встроенные системы (это требует минимального времени выполнения) или среда с ограниченными ресурсами, такие как Raspberry Pi, Arduino или робототехника
  • Инструменты или сервисы, которые не могут поддерживать долгие задержки, похожее содержится в системах компилятора Just In Time (JIT)
  • Web-фреймворки
  • Крупномасштабные, высокопроизводительные, ресурсоемкие и сложные программные системы

Rust особенно хорошо подходит, когда важно качество кода, это подходит для:

  • Небольшой или крупной команде разработчиков
  • Длительного использования кода в продакшене
  • Кода с долгим сроком службы, который будет требовать регулярного обслуживания и рефакторинга
  • Код, для которого вы обычно пишете много юнит-тестов, чтобы обеспечить его защиту

Даже перед появлением Rust 1.0, две компании уже использовали его в продакшене:

  • OpenDNS – это промежуточный инструмент для блокировки вредоносных программ и доменов
  • Skylight – это инструмент для мониторинга запущенных Rails приложений

Servo

Mozilla использовала Rust для написания Servo – нового движка для веб-браузеров, который разработан для многозадачности и безопасности.

Благодаря дизайну компилятора Rust, многие ошибки безопасности в браузере предотвращаются автоматически. В 2013, подключилась к разработке компания Samsung, портировав Servo на Android и ARM процессоры. Servo является проектом с открым исходным кодом, в котором уже более 200 контрибуций. Он находится в процессе разработки, и среди прочего, в нем уже реализован собственный парсер CSS3 и HTML5. Он прошел ACID2 тест в марте 2014 года.

Установка Rust

Скачать компилятор и инструменты можно можно на официальном сайте. Платформа поставляется для трех основных операционных систем (Linux 2.6.18 или более поздняя версия, OS X 10.7 или более поздняя версия, Windows 7, Windows 8 и Windows Server 2008 R2), в 32 и 64-битном формате. Вы должны использовать текущую стабильную версию 1.0, когда будете заниматься профессиональной работой с Rust. Если вы захотите использовать самую последнюю версию, можете установить версию ночной сборки.

Для Windwos, дважды кликните по инсталлятору .exe, для установки Rust и его зависимостей.

Для Linux и Mac OS X, самым простым способом будет ввести следующую команду в консоли:

curl -sSL https://static.rust-lang.org/rustup.sh | sh 

Проверить корректность установки можно с помощью просмотра текущей версии Rust в системе, для этого используйте rustc -V или rustc –version, вы увидите что-то наподобие этого:

# rustc -V rustc 1.0.0-beta.5 (7b4ef47b7 2015-05-11) (built 2015-05-11) 

Rust можно удалить с помощью C:\Rust\unins001.exe в Windwos, и с помощью /usr/local/lib/rustlib/uninstall.sh на Linux.

Rust также был портирован на Android OS, iOS и ARM процессоры.

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

Исходники Rust лежат на GitHub, и если вы захотите собрать Rust из исходников, можете почитать тут, как это сделать.

Rust компилятор – rustc

В установочной директории Rust лежит rustc, вы можете найти его в следующих директориях:

  • Для Windows – C:\Program Files\Rust 1.0\bin, если вы не меняли папку по умолчанию
  • Для Linux или Mac OS X – /usr/local/bin

Если домашняя директория Rust была прописана в путях консоли, то rustc можно вызывать из любого места терминала. Библиотеки Rust вы можете найти в папке rustlib каталога bin на Windows, или в /usr/local/lib/rustlib в Linux. HTML документация лежит в C:\Rust\share\doc\rust\html, в Windows, и /usr/local/share/doc/html в Linux.

Команды rustc имеют следующий формат: rustc [options] input.

В опциях указывается одна буква с одним тире, например -g или -W, или слово с двумя: –test, –no-analysis. Все варианты с пояснениями отображаются при вызове rustc -h.

Наша первая программа

Давайте начнем с сообщения приветствия нашим игрокам:

1. Создайте новый файл с помощью вашего любимого текстового редактора и введите туда следующий код:

fn main() { 	println!("Добро пожаловать в игру!"); } 

2. Сохраните файл, как welcome.rs
.rs – это стандартное расширение для файлов Rust. Имя файла не должно содержать пробелов, если вам необходимо разделить слова, то воспользуйтесь нижним подчеркиванием, например start_game.rs.

3. Дальше, нам нужно скомпилировать наш код, для этого введи в консоли следующее:

rustc welcome.rs 

Эта команда создаст файл welcome.exe в Windows и welcome в Linux.

4. Запустите программу, вы увидите следующее:

Добро пожаловать в игру! 

Выходной исполняемый файл получает такое же имя, какое имеет файл с исходным кодом. Если вы хотите задать выходному файлу другое имя, скажем start, скомпилируйте код с параметром -o имя_файла:

rustc welcome.rs -o start 

Параметр rustc -O произведет оптимизацию кода по скорости выполнения (это эквивалентно команде rustc -C opt-level=2, наиболее оптимизируем код генерируется с помощью opt-level=3).

Компиляция и запуск являются отдельными, последовательными шагами, которые противоречат динамическим языкам, таким как Python или Ruby, где эти действия выполняются в один шаг.

Поясним приведенный код выше. Если вы уже работали в таких средах, как C/Java/C#, этот код покажется вам знакомым. Как и в большинстве языков, выполнение кода начинается в функции main(), которая является обязательной в выполняемых программах.

В больших проектах, с множество исходных файлов, файл, содержащий функцию main() называется main.rs.

Мы видим, что main() объявлена, как функция, поскольку до имени предшествует ключевое слово fn, короткое и элегантное, как и большинство ключевых слов в Rust. В скобках main указывается список параметров, в нашем примере он пуст. Код функции помещен в блок, который окружен фигурными скобками {}. Открывающаяся фигурная скобка ставится на той же строке, где объявлялась функция, при этом отделяется пробелом. Закрывающаяся фигурная скобка ставится на новой строке, после окончания кода, на том же уровне, где располагается ключевое слово fn.

Наша программа имеет только одну строку, которая имеет отступ в четыре пробела, для удобства чтения (Rust не чувствителен к пробелам). Эта программа печатает строку “Добро пожаловать в игру!”, поскольку она окружена двойными кавычками. Это строка была передана, как параметр, макросу println! (восклицательный знак указывает на то, что это макрос, а не функция). Как и большинство строк в Rust (но не все), наша строчка кода заканчивается точкой с запятой.

Макрос println! имеет некоторые хорошие возможности форматирования, и одновременно проверяет при компиляции, корректен ли тип переменных для примененного форматирования.

Работаем с Cargo

Cargo – это менеджер пакетов и зависимостей в Rust, он похож на Bundler, npm, pub, или pip в других языках. Не смотря на то, что вы можете писать программы на Rust без него, Cargo незаменим для любого крупного проекта. Cargo устанавливается вместе с Rust и доступен из коробки.

Cargo делает следующие вещи для вас:

  • С помощью команды cargo new, он создает аккуратную структуру папок и некоторые шаблоны для вашего проекта
  • С помощь cargo build, он компилирует (собирает) ваш код
  • С помощью cargo run, он запускает ваш проект
  • С помощью cargo test, он может выполнить юнит-тесты, если ваш проект их содержит
  • С помощью cargo update, если ваш проект зависит от пакетов, он загрузит их и соберет эти пакеты, согласно вашим потребностям

Давайте переделаем наш проект, используя Cargo:

1. Создайте новый проект welcomec, используя следующую команду:

cargo new welcomec --bin 

Опция –bin говорит Cargo, что мы хотим создать выполняемую (бинарную) программу. После выполнения этой команды у нас будет следующая структура:

# cd welcomec/ welcomec # tree . ├── Cargo.toml └── src     └── main.rs   1 directory, 2 files 

Создается папка с названием проекта, в эту папку вы можете поместить все виды общей информации, файл лицензии, README файл и тд. В подпапке src лежит файл шаблона исходного кода, под названием main.rs (в нем содержится примерно такой же код, что мы писали, только выводится строка с надписью “Hello world!”).

Файл Cargo.toml (с заглавной буквой C) – это конфигурационный файл или манифест вашего проекта. В нем содержатся все метаданные, которые нужны Cargo для сборки вашего проекта. Он придерживается так называемому формату TOML, и содержит следующий текст с информацией о нашем проекте:

[package] name = "welcomec" version = "0.0.1" authors = ["Your name <you@example.com>"]" 

Этот файл можно редактировать и добавлять другие разделы. Например, мы можем добавить раздел, в котором будем говорить Cargo, что хотим, чтобы проект компилировался с именем welcome:

[[bin]] name = "welcome" 

2. Мы можем собрать проект (независимо от того, сколько исходных файлов он содержит), используя следующую команду:

cargo build 

По завершению сборки будет выдано следующее сообщение (на Linux):

Compiling welcomec v0.1.0 (file:///home/ska1n/Source/rust/welcomec) 

Теперь, в нашем проекте вот такая структура каталогов:

welcomec # tree . ├── Cargo.lock ├── Cargo.toml ├── src │   └── main.rs └── target     └── debug         ├── build         ├── deps         ├── examples         ├── native         └── welcomec   7 directories, 4 files 

В каталоге target лежит наш исполняемый файл welcome.

3. Для запуска программы, используйте следующую команду:

cargo run 

Будет выдан следующий результат:

Running `target/debug/welcomec` Hello, world! 

На втором шаге также также создается файл с именем Cargo.lock. Его использует Cargo для отслеживания зависимостей в вашей проекте. На данный момент в нем содержится только информация о приложение:

[root] name = "welcomec" version = "0.0.1" 

В таком же формате файла используется контроль версий библиотек или пакетов, от которых будет зависеть ваш проект. Если ваш проект планируется собирать в будущем, когда будут доступны свежие версии библиотек, Cargo убедится в том, что версии, записанные в Cargo.lock не создадут несовместимость версий при сборке проекта. Это обеспечивает повторимость процесса сборки.

Инструменты разработки

Так как Rust является системным языком программирования, единственная вещь, которая вам понадобится – это хороший текстовый редактор (но не текстовой процессор!) для написания исходного кода, а все остальное можно сделать в терминале. Однако, некоторые разработчики ценят функциональность, которую предлагают более полноценные текстовые редакторы, используемые специально для программирования или IDE (интегрированная среда разработки). Rust все еще молод, но уже сейчас может предложить много возможностей на этом фронте, хотя некоторые из них должны обновиться с последней версией Rust.

Создано множество Rust плагинов для текстовых редакторов, таких как Atom, Brackets, BBEdit, Emacs, Geany, GEdit, Kate, TextMate, Textadept, Vim, NEdit, Notepad++, и SublimeText. Большинство Rust разработчиков работают с Vim или Emacs. Для этих редакторов создан проект, под названием racer. Он идет с подсветкой синтаксиса и автозавершением кода.

Другие инструменты

RustDT – это новый и многообещающий Rust IDE, основанный на Ecplise. Поверх всей функциональности редактирования, предлагаемой Eclipse, он использует Cargo. Кроме того, он имеет в своем функционале автозавершение кода и систему отладки (использует отладчик GDB).

Существуют также плагины для других IDE, с разным состоянием завершенности:

Еще вы можете протестировать Rust код, даже если у вас он не установлен на локальной машине, с помощью сервиса Rust Play Pen. Здесь можно отредактировать или вставить код и оценить его.

rusti – это простая интерактивная среда программирования (REPL), которая разрабатывается для Rust. Такая среда характерна для динамических языков, но это удивительно для статически компилируемого языка.

Так же эту, статью можно почитать здесь — notegeek.org/rust/603

ссылка на оригинал статьи http://habrahabr.ru/post/260147/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *