Rust для JS разработчиков
Перевод | Автор оригинала: David Morcillo
Хорошее введение в Rust с точки зрения разработчика JavaScript.
Когда я впервые прочитал про Rust, это не вызвало у меня интереса. Около двух лет назад я работал веб-разработчиком, в основном используя JavaScript, и подумал, что Rust не для меня, потому что в тот момент это выглядело очень сложно.
В начале этого года я решил начать изучать Rust самостоятельно. Что изменилось за это время? Я все еще веб-разработчик, но знание того, что я смогу написать программу на Rust, скомпилировать ее в WebAssembly и выполнить ее в браузере, было той искрой, которая зажгла мою мотивацию.
В этом посте я собираюсь представить Rust с точки зрения разработчика JavaScript, сделав несколько параллельных сравнений. Надеюсь, это мотивирует вас попробовать!
Что такое Rust?
Язык программирования Rust был создан Mozilla, а его первая стабильная версия была выпущена примерно в 2015 году. Это выглядит так:
fn main() {
println!("Hello, World!");
}
Выглядит не так уж и страшно, правда? Можно сказать, что это почти похоже на JavaScript, но это просто программа hello world, и она немного сложнее! Прежде чем рассматривать некоторые особенности языка, давайте поместим Rust в спектр языков программирования следующим образом:
Существует четкое различие между языками программирования:
- Низкоуровневый: такие языки, как C++, которые имеют доступ к управлению памятью, считаются низкоуровневыми и работают очень быстро. Они также очень небезопасны, потому что очень легко испортить память, и могут случиться плохие вещи!
- Высокий уровень: с другой стороны, такие языки, как JavaScript, не имеют такого детального доступа к памяти (есть сборщик мусора, который обрабатывает все за нас) и считаются безопасными языками, поэтому иногда они могут быть медленными.
Rust можно считать быстрым и безопасным, но он не дается бесплатно: требуется крутая кривая обучения, а время компиляции может быть немного большим даже для небольших примеров.
Ключевые особенности Rust
Как и любому языку программирования, здесь есть что охватить, но я решил сосредоточиться на четырех темах, которые необходимы для изучения языка и начала работы над ним.
Типы
JavaScript - это язык с динамической типизацией, и мы можем делать некоторые забавные вещи, например вычитать число 1 из строки wat и получать неожиданные результаты. Это возможно, потому что система типов не является строгой. В Rust, если вы попытаетесь выполнить простое сложение двух чисел разного типа, вы получите ошибку компиляции:
fn main() {
let a: i32 = 42;
let b: f64 1.0;
println!("{}", a + b); // ERROR: a and b are not of the same type.
}
Когда вы начнете работать с Rust, у вас будет много ошибок, и вы, вероятно, сначала возненавидите компилятор:
Piture: Некоторые
Если вы чувствуете себя этой собакой и постоянно боретесь с компилятором Rust, не волнуйтесь! Все мы были там.
Неизменность
Функциональные языки хорошо известны тем, что работают с неизменяемыми структурами. Как разработчики JavaScript, мы не обязаны работать с неизменяемостью, но популярные библиотеки, такие как Redux и Immutable.js, научили нас этим передовым методам. Сегодня у нас есть ключевые слова let и const для объявления изменяемых и неизменяемых переменных соответственно.
В Rust мы будем использовать let для объявления переменных, и по умолчанию они будут неизменяемыми. Если мы хотим использовать изменяемые данные, нам нужно добавить ключевое слово mut в объявление следующим образом:
fn main() {
let a = 42;
let mut b = 1;
a = 43; // ERROR: a is not mutable
b = 2;
}
Право собственности
На мой взгляд, это самая сложная концепция для изучения Rust, потому что она действительно отличается от других языков, над которыми я работал, но это ключ, который делает Rust быстрым и безопасным в использовании!
Когда вы назначаете некоторые данные переменной, говорят, что они принадлежат переменной, и у каждой части данных может быть только один владелец. Давайте посмотрим на это в действии:
fn main() {
let x = String::from("hello"); // x owns the "hello" string
let a = x; // At this point a owns the "hello" string and x is no longer valid
do_something(x); // ERROR: x cannot be used anymore!
}
В Rust нет нулевых и неопределенных значений, поэтому мы не можем использовать переменную, у которой нет значения. В предыдущем примере, когда мы присвоили x, мы перемещаем значение из x в a, поэтому в этот момент x не имеет допустимого значения. То же самое и с функциями:
fn main() {
let x = String::from("hello");
do_something(x);
do_other_thing(x); // ERROR: x cannot be used anymore!
}
fn do_something(s: String) {
// Do something with s
}
Когда мы вызываем метод do_something, мы перемещаем значение из x в s, аргумент, полученный функцией. После выполнения функции мы возвращаемся в main, и x больше не имеет допустимого значения.
Предыдущее поведение не всегда желательно, и поэтому в Rust мы можем заимствовать вещи! Если вы не хотите перемещать значение из одной переменной в другую, используйте такие ссылки:
fn main() {
let x = String::from("hello");
do_something(&x);
do_other_thing(&x); // This is ok now because we are not moving the value
}
fn do_something(s: &String) {
// Do something with s
}
Когда мы имеем дело с владением и заимствованием, компилятор Rust хочет, чтобы мы играли хорошо, поэтому он предупредит нас, если вы попытаетесь сделать что-то не так.
Если вы запутались, узнав о владении и заимствовании, ничего страшного! Ваш мозг начал заниматься управлением памятью, и иногда это может причинять боль. Я рекомендую вам посмотреть это видео, чтобы узнать больше по этой теме.
Структуры
Rust не является объектно-ориентированным языком, но у него есть некоторые функции, которые могут имитировать поведение, присутствующее в таких языках. Когда мы работаем с классами в JavaScript, мы имеем дело и с данными, и с методами в одном и том же месте. В Rust мы собираемся отделить представление данных от методов, которые ими управляют, следующим образом:
struct Dog {
name: String,
score: i32
}
impl Dog {
fn say_something(self: &Dog) {
println!("Hey, my name is {}... I mean WOOF!", self.name);
}
}
fn main() {
let dog = Dog { name: String::from("Boira"), score: 13 };
dog.say_something();
}
Структура Dog очень похожа на объект JavaScript, но это не так. Структура - это форма некоторых данных, которые будут иметь два именованных поля: имя и оценка. Под структурой вы можете увидеть блок реализации (для краткости подразумеваемый). Мы можем объявить методы, которые будут манипулировать данными подобным образом, и заметить, что если мы хотим связать функцию с этими данными, нам нужно передать self в качестве первого аргумента. Это вроде как Python, не так ли?
Если мы опускаем самооценку, мы объявляем метод, не связанный с какой-либо конкретной частью данных. Вы можете думать об этом как о статическом методе в классе JavaScript.
Что я могу делать с Rust?
Первое, что вам нужно сделать, это установить Rust, и это не может быть проще. Посетите сайт https://rustup.rs/, чтобы загрузить официальный установщик набора инструментов. Это похоже на проект nvm, который обычно используется с JavaScript.
Тогда вам понадобятся некоторые библиотеки, поэтому не начинайте с нуля. Точно так же, как у нас есть пакеты Node в JavaScript, мы будем иметь дело с крэйтами в Rust. Посетите crates.io, официальный реестр крэйтов, чтобы узнать больше о крэйтах Rust.
Поскольку Rust очень универсален, существует множество тем, в которых можно использовать Rust, и сообщество приложило все усилия, чтобы отслеживать их на разных веб-сайтах:
-
www.arewewebyet.org: Даже если не существует таких зрелых фреймворков, как Ruby on Rails, вы могли бы построить кое-что! Я рекомендую взглянуть на фреймворк Rocket, если вы хотите заняться веб-разработкой. Вы даже можете создавать API-интерфейсы GraphQL с помощью Juniper!
-
www.arewegameyet.com: Полный контроль над управлением памятью необходим для создания игр, так что Rust - прекрасный кандидат! Если вас интересует разработка игр, я рекомендую вам проверить игровой движок Amethyst.
-
www.arewelearningyet.com: Еще одна тема, которая сейчас широко популярна, - это машинное обучение. Экосистема Rust на данный момент не очень завершена, и, возможно, сейчас она не так хороша, как Python, для машинного обучения, но если вам интересна тема, проверьте их веб-сайт!
Наконец, если вы занимаетесь веб-разработкой, вам повезло! Вы можете создавать программы, компилировать их и использовать все вместе с существующим кодом JavaScript. Технология, которая сделала это возможным, - это WebAssembly, и ее можно использовать прямо сейчас во всех современных браузерах.
Если вы хотите попробовать, я рекомендую вам прочитать официальную книгу Rust и WebAssembly.
Вывод
Rust - действительно крутой язык для изучения, и с его помощью можно построить много чего! Если вы веб-разработчик, как и я, вам будет очень интересна вся тема WebAssembly, и я надеюсь, что смогу писать об этом в будущих сообщениях.
Если вы хотите начать работать с Rust, я рекомендую вам заглянуть в официальную книгу и попробовать написать некоторые существующие программы JavaScript с Rust. Ведь во многом практика - ключ к успеху!
Наконец, этот пост был вдохновлен докладом, который я представил на встрече JS Coders, и вы можете проверить слайды здесь.
Фотография на обложке: Phil Hearing.