Rust — молодой и дерзкий язык программирования

Пер­вая вер­сия язы­ка Rust появи­лась в 2010 году, и он сра­зу занял тре­тью строч­ку в спис­ке люби­мых язы­ков раз­ра­бот­чи­ков на StackOverflow. Год спу­стя Rust воз­гла­вил этот спи­сок и дер­жал­ся там несколь­ко лет. Давай­те посмот­рим, поче­му этот язык стал таким попу­ляр­ным, в чём его осо­бен­но­сти и поче­му вокруг него мно­го спо­ров.

В чём идея языка Rust

Авто­ру язы­ка нра­ви­лась ско­рость рабо­ты и все­мо­гу­ще­ство язы­ка C++ и надёж­ность Haskell. Он поста­вил перед собой зада­чу сов­ме­стить оба этих под­хо­да в одном язы­ке, и за несколь­ко лет он собрал первую вер­сию язы­ка Rust.

Rust пози­ци­о­ни­ру­ет­ся как ком­пи­ли­ру­е­мый систем­ный муль­ти­па­ра­диг­маль­ный язык высо­ко­го уров­ня. Сей­час пояс­ним, что это зна­чит.

👉 Ком­пи­ли­ру­е­мый язык озна­ча­ет, что гото­вая про­грам­ма — это отдель­ный файл, кото­рый мож­но запу­стить на любом ком­пью­те­ре с нуж­ной опе­ра­ци­он­ной систе­мой. Для запус­ка не нуж­но уста­нав­ли­вать сре­ду раз­ра­бот­ки и ком­пи­ля­тор, доста­точ­но, что­бы ском­пи­ли­ро­ван­ная вер­сия под­хо­ди­ла к ваше­му ком­пью­те­ру. 

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

👉 Муль­ти­па­ра­диг­маль­ный зна­чит, что в язы­ке соче­та­ют­ся несколь­ко пара­дигм про­грам­ми­ро­ва­ния. В слу­чае Rust это ООП, про­це­дур­ное и функ­ци­о­наль­ное про­грам­ми­ро­ва­ние. При­чём, ООП в Rust при­шло из C++, а функ­ци­о­наль­ное — из Haskell. Про­грам­мист может сам выби­рать, в каком сти­ле он будет писать код, или сов­ме­щать раз­ные под­хо­ды в раз­ных эле­мен­тах про­грам­мы.

Синтаксис и код

За осно­ву син­так­си­са в Rust взят син­так­сис из C и C++.Например, клас­си­че­ский «При­вет, мир!» на Rust выгля­дит так:

fn main() {
    println!("Hello, world!");
}

Если вы зна­ко­мы с подоб­ным син­так­си­сом, то смо­же­те быст­ро начать писать и на Rust. Дру­гое дело, что в Rust есть свои осо­бен­но­сти:

  • пере­мен­ные менять нель­зя, а если нуж­но — при объ­яв­ле­нии ука­зы­ва­ют клю­че­вое сло­во mutable;
  • все коман­ды внут­ри услов­ных опе­ра­то­ров, цик­лов и дру­гих блоч­ных кон­струк­ций обя­за­тель­но брать в фигур­ные скоб­ки, даже если там будет все­го одна коман­да;
  • аргу­мен­ты у услов­ных опе­ра­то­ров, напри­мер if или while, в скоб­ки брать не нуж­но;
  • при объ­яв­ле­нии пере­мен­ной мож­но исполь­зо­вать услов­ный опе­ра­тор:

let x = if new_game() { 4 }
    else if reload() { 3 }
  else { 0 }

Послед­нее раз­бе­рём подроб­но. При такой запи­си пере­мен­ная x будет рав­на четы­рём, если функ­ция new_game() вер­нёт зна­че­ние true. Если это­го не слу­чит­ся, ком­пи­ля­тор вызо­вет функ­цию reload() и про­ве­рит, что полу­чи­лось. Если true, то x при­мет зна­че­ние 3, а если и это не сра­бо­та­ет — то x ста­нет рав­ным 0.

Ещё в Rust есть срав­не­ние пере­мен­ной с образ­цом. В зави­си­мо­сти от того, с каким образ­цом сов­па­ло зна­че­ние пере­мен­ной, выпол­нит­ся та или иная функ­ция:

// смотрим, что лежит в переменной my_number и в зависимости от этого выводим что-то на экран
alt my_number {
  0       { std::io::println("Ноль"); }
  1 | 2   { std::io::println("Один или два"); }
  3 to 10 { std::io::println("От трёх до десяти"); }
  _       { std::io::println("Что-то другое…"); }
}

Главная особенность программ на Rust

Несмот­ря на син­так­сис, похо­жий на C, глав­ную осо­бен­ность про­грамм на Rust раз­ра­бот­чи­ки взя­ли из Haskell, и зву­чит она так:

Если про­грам­ма на Rust ском­пи­ли­ро­ва­лась и не упа­ла во вре­мя запус­ка, то она будет рабо­тать до тех пор, пока вы сами её не оста­но­ви­те.

Это зна­чит, что про­грам­мы на Rust почти так же надёж­ны, как про­грам­мы на Haskell. Почти — пото­му что если про­грам­мист исполь­зу­ет «небез­опас­ный» блок unsafe, кото­рый даёт ему пря­мой доступ к памя­ти, то в тео­рии это ино­гда может при­ве­сти к сбо­ям. Но даже с таки­ми бло­ка­ми Rust ста­ра­ет­ся справ­лять­ся сам и пада­ет толь­ко в без­на­дёж­ных слу­ча­ях.

Плюсы и минусы языка

Когда язык сов­ме­ща­ет в себе несколь­ко раз­ных под­хо­дов из дру­гих язы­ков, он полу­ча­ет боль­шин­ство пре­иму­ществ каж­до­го из них:

  • высо­кая ско­рость рабо­ты про­грамм;
  • воз­мож­ность напи­сать код в ООП-стиле: с клас­са­ми и объ­ек­та­ми (но есть огра­ни­че­ния);
  • ста­биль­ность в рабо­те и при ком­пи­ля­ции;
  • ком­пи­ля­тор сам пред­ла­га­ет вари­ан­ты исправ­ле­ния оши­бок в коде;
  • кросс-платформенный ком­пи­ля­тор;
  • под­держ­ка мно­го­по­точ­но­сти;
  • под­держ­ка «небез­опас­ных» бло­ков для пря­мой рабо­ты с памя­тью;
  • мож­но встав­лять код на C и C++.

Мину­сы в основ­ном свя­за­ны со ско­ро­стью раз­ви­тия язы­ка. Так как Rust раз­ви­ва­ет­ся очень быст­ро, то часто быва­ет так, что код из ста­рой вер­сии не рабо­та­ет в новой вер­сии. Ещё к мину­сам мож­но доба­вить:

  • избы­точ­ную доку­мен­та­цию, кото­рая ино­гда про­ти­во­ре­чит сама себе;
  • меня­ю­щий­ся от вер­сии к вер­сии син­так­сис;
  • непол­ную под­держ­ку ООП и слож­ную рабо­ту с объ­ек­та­ми и насле­до­ва­ни­ем.

Что написано на Rust

Чаще все­го Rust исполь­зу­ют в тех про­ек­тах, где нуж­на ста­биль­ность и надёж­ность при высо­кой нагруз­ке и общее быст­ро­дей­ствие про­грам­мы.

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

  • Dropbox — сер­вер­ная часть, кото­рая отве­ча­ет за син­хро­ни­за­цию.
  • Coursera — боль­шая часть фронт- и бэкен­да напи­са­на на Rust.
  • Mozilla: Firefox и sccache (рас­пре­де­лён­ный кэш для ком­пи­ля­то­ра).
  • OpenDNS — сер­вис для исполь­зо­ва­ния обще­до­ступ­ных DNS-сервисов.
  • Servo — бра­у­зер­ный дви­жок с мно­го­по­точ­но­стью.
  • Twitter — исполь­зу­ет Rust для высо­ко­на­гру­жен­ной части сер­ви­са.

Текст:
Миша Поля­нин

Редак­тор:
Мак­сим Илья­хов

Кор­рек­тор:
Ира Михе­е­ва

Иллю­стра­тор:
Даня Бер­ков­ский

Вёрст­ка:
Маша Дро­но­ва

Достав­ка:
Олег Веш­кур­цев