Rust (мова програмування)
Rust — мова програмування, яку розробляє Mozilla Research[2]. Мова має сувору типізацію і сфокусована на безпечній роботі з пам'яттю і забезпеченні високого паралелізму виконання завдань (можливість породжувати тисячі і навіть мільйони підпроцесів).
Rust | |
---|---|
Парадигма | компільована, паралельна, функційна, імперативне, об'єктно-орієнтована, структурна |
Дата появи | 2010 |
Творці | Graydon Hoare |
Розробник | Rust Project Developers |
Останній реліз | 1.54.0 (29 липня 2021 ) |
Система типізації | статична, cильна, вивід типів, структурна |
Під впливом від | Alef, C#, C++, Camlp4, Common Lisp, Cyclone, Erlang, Haskell, Hermes, Limbo, Napier, Napier88, Newsqueak, NIL, Ocaml, Ruby, Sather, Standard ML |
Операційна система | Linux, Mac OS X, Windows, FreeBSD |
Ліцензія | Apache License 2.0 або MIT License[1] |
Звичайні розширення файлів |
.rs |
Репозиторій вихідного коду | github.com/rust-lang/rust |
Вебсайт | www.rust-lang.org |
Rust у Вікісховищі |
Початковий код проекту поширюються під ліцензією MIT.
Історія
Робота над мовою була розпочата Грейдоном Гоаром в 2006 році, в 2009[3] до розробки підключилася Mozilla, і в 2010 році мова була офіційно представлена на Mozilla Summit 2010[4]. Мову названо за назвою родини грибів Іржа.[5] У 2010 році розробка мови була переведена з попередньої версії компілятора, яка була написана мовою OCaml, на компілятор, який написаний безпосередньо на Rust, з використанням LLVM як бекенду[6]. У 2011 році новий компілятор успішно скомпілював сам себе[7].
Перший стабільний випуск мови Rust 1.0 відбувся 15 травня 2015[8] після п'яти років розробки, він ознаменував повну стабілізацію програмних інтерфейсів усіх бібліотек і мовних конструкцій. В процесі підготовки гілки Rust 1.0 програмних інтерфейсів і можливості мови піддалися значній ревізії, після якої за умовчанням залишені тільки повністю готові до застосування можливості, реалізація яких не змінюватиметься надалі. Усі інші функції переведені в розряд експериментальних і винесені з постачання за умовчанням.
Паралельно Mozilla Research розвиває експериментальний браузерний рушій Servo, написаний мовою Rust з підтримкою багатониткового рендерингу веб-сторінок і розпаралелюванням операцій з DOM (Document Object Model), а компанія Samsung займається його портуванням на Android та ARM процесори[9].
Огляд
За структурою мова Rust нагадує C++, але істотно відрізняється в деяких деталях реалізації синтаксису і семантики, а також орієнтацією на блокову організацію структури коду, яка дозволяє реалізувати завдання у вигляді легковагих співпрограм. Автоматичне керування пам'яттю позбавляє розробника необхідності маніпулювання вказівниками і захищає від проблем, що виникають через низькорівневу роботу з пам'яттю, таких як звернення до області пам'яті після її звільнення, розіменовування нульових вказівників, вихід за межі буфера тощо. Rust підтримує суміш імперативних процедурних і об'єктно-орієнтованих методів з такими парадигмами, як функційне програмування і модель акторів, а також узагальнене програмування і метапрограмування, в статичних і динамічних стилях.
Особливості
Базові можливості мови:
- Орієнтація на безпеку
- Акуратна робота з пам'яттю — ніяких нульових і втрачених вказівників. Автоматичне керування пам'яттю;
- Контроль мінливості. Об'єкти незмінні (Immutable) за умовчанням;
- Безпека динамічного виконання: обробка збоїв, винятки, ведення логу, RAII/dtors;
- Typestate: можливість визначення складних інваріантів, що контролюють структури даних.
- Орієнтація на паралельність і ефективність коду
- Явний контроль пам'яті, контролювання схеми розподілу пам'яті;
- Вкрай легкі завдання, що формуються у вигляді співпрограми. Легкість в породження тисяч і мільйонів підпроцесів;
- Ітератори стека (фактично лямбда-блоки без розподілу купи);
- Статична, нативна компіляція із створенням виконуваних файлів ELF, Portable Executable, Шаблон:Mach-O;
- Прямий і простий інтерфейс для коду на мові Сі;
- Орієнтація на практичне застосування
- Мультипарадигмальний, функціональний, імперативно-процедурний, об'єктно-орієнтована, підтримка паралельної actor-моделі;
- Функції вищого порядку із зв'язуванням (біндінгами);
- Немає номінальних типів або ієрархії типів;
- Мульти-платформовий, підтримується Windows, Linux, Mac OS X, *BSD;
- Зберігання рядків у UTF8, різноманітність низькорівневих типів;
- Працює з існуючими нативними наборами інструментів: GDB, Valgrind, Shark тощо;
- Практична можливість порушення правил: можливість ігнорування правил безпеки, якщо чітко вказано, коли і як їх порушувати.
Приклади
Наведені нижче приклади є робочими при складанні за допомогою стабільної версії компілятора Rust 1.0.0.
fn main() {
println!("hello, world");
}
Три версії реалізації функції пошуку факторіала, в рекурсивному та ітеративному стилях:
// Умовний оператор, що показує можливість неявного повернення значення (implicit return).
// На відміну від C++ і схожих мов, у Rust оператор «if» насправді є виразом, і може повертати значення.
fn recursive_factorial(n: u32) -> u32 {
if n <= 1 {
1
} else {
n * recursive_factorial(n - 1)
}
}
fn iterative_factorial(n: u32) -> u32 {
// Variables are declared with `let`.
// The `mut` keyword allows these variables to be mutated.
let mut i = 1u32;
let mut result = 1u32;
while i <= n {
result *= i;
i += 1;
}
return result; // An explicit return, in contrast to the prior function.
}
fn iterator_factorial(n: u32) -> u32 {
// Iterators have a variety of methods for transformations.
// |accum, x| defines an anonymous function.
// Optimizations like inline expansion reduce the range and fold
// to have performance similar to iterative_factorial.
(1..n + 1).fold(1, |accum, x| accum * x)
}
fn main() {
println!("Recursive result: {}", recursive_factorial(10));
println!("Iterative result: {}", iterative_factorial(10));
println!("Iterator result: {}", iterator_factorial(10));
}
Демонстрація вбудованих в Rust унікальних розумних вказівників, разом з тип-сумами та методами:
use IntList::{Node, Empty};
// This program defines a recursive datastructure and implements methods upon it.
// Recursive data structures require a layer of indirection, which is provided here
// by a unique pointer, constructed via the `Box::new` constructor. These are
// analogous to the C++ library type `std::unique_ptr`, though with more static
// safety guarantees.
fn main() {
let list = IntList::new().prepend(3).prepend(2).prepend(1);
println!("Sum of all values in the list: {}.", list.sum());
println!("Sum of all doubled values in the list: {}.", list.multiply_by(2).sum());
}
// `enum` defines a tagged union that may be one of several different kinds of values at runtime.
// The type here will either contain no value, or a value and a pointer to another `IntList`.
enum IntList {
Node(i32, Box<IntList>),
Empty
}
// An `impl` block allows methods to be defined on a type.
impl IntList {
fn new() -> Box<IntList> {
Box::new(Empty)
}
fn prepend(self, value: i32) -> Box<IntList> {
Box::new(Node(value, Box::new(self)))
}
fn sum(&self) -> i32 {
// `match` expressions are the typical way of employing pattern-matching,
// and are somewhat analogous to the `switch` statement from C and C++.
match *self {
Node(value, ref next) => value + next.sum(),
Empty => 0
}
}
fn multiply_by(&self, n: i32) -> Box<IntList> {
match *self {
Node(value, ref next) => Box::new(Node(value * n, next.multiply_by(n))),
Empty => Box::new(Empty)
}
}
}
Наступний зразок потребує для своєї роботи «нічну» збірку компілятора, оскільки модуль thread залишається нестабілізованою функціональністю, що заблокована для використання в каналах бета- та стабільних випусків.
Проста демонстрація легковагих можливостей паралелізму Rust:
#![feature(scoped)]
use std::thread;
// This function creates ten threads that all execute concurrently.
// To verify this, run the program several times and observe the irregular
// order in which each thread's output is printed.
fn main() {
// This string is immutable, so it can safely be accessed from multiple threads.
let greeting = "Hello";
let mut threads = Vec::new();
// `for` loops work with any type that implements the `Iterator` trait.
for num in 0..10 {
threads.push(thread::scoped(move || {
// `println!` is a macro that statically typechecks a format string.
// Macros are structural (as in Scheme) rather than textual (as in C).
println!("{} from thread number {}", greeting, num);
}));
}
// The `threads` `Vec` is destroyed here and scoped thread handles are
// destroyed after joining.
}
Примітки
- COPYRIGHT. Rust compiler source repository. Процитовано 17 грудня 2012.
- The Rust Language. Lambda the Ultimate. 8 липня 2010. Архів оригіналу за 23 листопада 2012. Процитовано 30 жовтня 2010.
- Project FAQ. 14 вересня 2010. Процитовано 17 квітня 2012.
- Future Tense. 29 квітня 2011. Архів оригіналу за 18 вересня 2012. Процитовано 17 квітня 2012. «At Mozilla Summit 2010, we launched Rust, a new programming language motivated by safety and concurrency for parallel hardware, the “manycore” future which is upon us.»
- Hoare, Graydon (7 червня 2014). Internet archaeology: the definitive, end-all source for why Rust is named "Rust". Reddit.com. Процитовано 4 лютого 2018.
- Hoare, Graydon (2 жовтня 2010). Rust Progress. Архів оригіналу за 18 вересня 2012. Процитовано 17 квітня 2012.
- Hoare, Graydon (20 квітня 2011). [rust-dev] stage1/rustc builds. Процитовано 17 квітня 2012. «After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :)»
- Announcing Rust 1.0
- Samsung teams up with Mozilla to build browser engine for multicore machines. Ars Technica. Процитовано 24 жовтня 2015.
Посилання
- Офіційний сайт
- Rust Language Wiki
- Електронний архів email листування Rust-dev
- Основний репозиторій вихідних текстів та баг-трекер