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 заключался в выполнении следующей команды:
Традиционный hello world:
println ! ( «Hello!» )
}
Восклицательный знак означает всего лишь, что println в Rust — это макрос (не имеет ничего общего с макросами в Си).
Компилируем, запускаем:
./hello
Теперь рассмотрим пример поинтереснее. Напишем программу, которая на вход принимает список URL, а возвращает HTML-код списка ссылок, в котором в качестве текста ссылок использовались соответствующие title.
Создадим новый проект:
Откроем файл Cargo.toml и исправим его таким образом:
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 напишем:
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>»»