Rust — это язык программирования общего назначения от компании Mozilla, разрабатываемый с 2010-го года. Разработчики Rust ставят перед собой задачу с одной стороны достичь производительности C/C++ (все же понимают, DSL’ем для разработки какого браузера является Rust?), а с другой — умудриться сделать язык высокоуровневым и безопасным. К окончанию 2014-го года планируется выпустить бета-версию Rust 1.0. Если все пойдет хорошо, нас ждет релиз Rust 1.0, после чего Mozilla обещает перестать ломать обратную совместимость.

В отношении Rust справедливо следующее:

  • Язык является кроссплатформенным, поддерживаются Windows (>= 7, на данный момент только x86), а также Linux и MacOS (x86 и amd64);
  • Компилятор Rust написан на Rust и использует LLVM;
  • Многое было позаимствовано из мира ФП — лямбды, замыкания, кортежи, алгебраические типы данных , паттерн матчинг, fold, map, filter, переменные по умолчанию неизменяемы;
  • Используется строгая статическая типизация с автоматическим выводом типов;
  • В языке есть метапрограммирование (типизированное);
  • Есть генерики, наследования как такового нет, только тайпклассы;
  • Нет неявного преобразования типов, размер примитивных типов как правило не зависит от платформы, нет никакого null;
  • Язык поддерживает Unicode, все строки хранятся в UTF-8 (подобно тому, как это сделано в Vala ) вместе с длиной и могут содержать в себе нулевые символы;
  • В стандартной библиотеке есть легковесные потоки (upd: выпилили ) и типизированные каналы для взаимодействия между ними, а также футуры ;
  • У языка нет полноценного GC, данные размещаются либо в стеке, либо в куче, но память освобождается при выходе из скоупа, либо используются счетчики ссылок (для смелых есть и обычные ссылки);
  • Компилятор очень жестко следит за тем, как вы работаете с памятью, например, если он заподозрит возможность состояния гонки, программа не скомпилируется;
  • При очень сильном желании эти проверки можно обойти, что особенно удобно, например, если вы хотите слинковаться с кодом на Си;
  • Rust имеет некоторый рантайм, но на языке также можно писать и без рантайма, что позволяет использовать Rust в задачах типа разработки ядра ОС;

Идею, как я лично ее понял, можно описать примерно так. Вот у нас есть всякие языки с GC типа Java и Go. И из-за этого GC они тормозят. И есть Си, который не тормозит, но в нем можно наделать кучу ошибок, из которых многие как раз связаны с управлением памятью. А давайте возьмем Си, избавим его от родовых травм (уберем инклуды, добавим генерики, кортежи, алгебраические типы данных и тд), а касательно сборки мусора скажем следующее. Вот у сишников есть определенные паттерны управления памятью (см например RAII ). Давайте использовать эти паттерны и напишем такой умный компилятор, который сделает очень сложным написание кода, в котором что-то течет или ссылается в никуда. Получим и скорость и безопасность.

Но хватит теории, перейдем к практике.

На момент написания этих строк самый простой способ установить последнюю версию Rust под Ubuntu Linux заключался в выполнении следующей команды:

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

Традиционный hello world:

fn main ( ) {
println ! ( «Hello!» )
}

Восклицательный знак означает всего лишь, что println в Rust — это макрос (не имеет ничего общего с макросами в Си).

Компилируем, запускаем:

rustc hello.rs
./hello

Теперь рассмотрим пример поинтереснее. Напишем программу, которая на вход принимает список URL, а возвращает HTML-код списка ссылок, в котором в качестве текста ссылок использовались соответствующие title.

Создадим новый проект:

cargo new shownotegen —bin

Откроем файл Cargo.toml и исправим его таким образом:

[package]

name = «shownotegen»
version = «0.0.1»
authors = [«Aleksander Alekseev <mail@remontka.com>»]

[[bin]]
name=»main»
path=»src/main.rs»

[dependencies.http]
git = «https://github.com/chris-morgan/rust-http.git»

В файле src/main.rc напишем:

#! [ feature ( phase ) ]

extern crate http ;
extern crate url ;
extern crate regex ;

# [ phase ( plugin ) ]
extern crate regex_macros ;

use http :: client :: RequestWriter ;
use http :: method :: Get ;
use std :: { os , str } ;
use url :: { Url , ParseError } ;
use std :: io :: { BufferedReader , File , IoError } ;

# [ deriving ( Show ) ]
enum GetTitleError {
InvalidUrl ( ParseError ) ,
RequestSendFailed ( IoError ) ,
ResponseReadFailed ( IoError ) ,
BodyDecodeFailed ,
ParseFailed
}

fn main ( ) {
let args = os :: args ( ) ;
match args. len ( ) {
0 => unreachable ! ( ) ,
2 => {
let path = Path :: new ( args [ 1 ] . as_slice ( ) ) ;
let mut file = BufferedReader :: new ( File :: open ( & path ) ) ;
for line in file. lines ( ) {
let tmp = line. unwrap ( ) ;
let url = tmp. trim ( ) ;
let text = match get_title ( url. as_slice ( ) ) {
Ok ( title ) => title ,
Err ( err ) => format ! ( «NO TITLE ({})» , err ) . to_string ( ) ,
} ;
println ! ( «<li><a href= » {} «» >{}</a></li>»» url text ) ;
}
}
_ => println ! ( «»Usage: {} <file>»»

EnglishRussianUkrainian