Rust (мова програмування)

Матеріал з Вікіпедії — вільної енциклопедії.
(Перенаправлено з Rust)
Перейти до: навігація, пошук
Rust
Rust programming language black logo.svg
Парадигма: компільована, паралельна, функційна, імперативне, об'єктно-орієнтована, структурна
Дата появи: 2010
Творці: Graydon Hoare
Розробник: Rust Project Developers
Останній реліз: 1.1 (25 червня 2015; 5 днів тому)
Система типізації: статична, сувора, вивід типів, структурна
Під впливом від: 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
Сторінка інтернет: www.rust-lang.org

Rust — експериментальна мова програмування, що розробляється Mozilla Research[2]. Мова має сувору типізацію і сфокусована на безпечній роботі з пам'яттю і забезпеченні високого паралелізму виконання завдань (можливість породжувати тисячі і навіть мільйони підпроцесів).

Сирцевий код проекту поширюються під ліцензією MIT.

Історія[ред.ред. код]

Робота над мовою була розпочата Грейдоном Гоаром в 2006 році, в 2009[3] до розробки підключилася Mozilla, і в 2010 році мова була офіційно представлена на Mozilla Summit 2010[4]. Також в 2010 році розробка мови була переведена з попередньої версії компілятора, яка була написана мовою OCaml, на компілятор, який написаний безпосередньо на Rust, з використанням LLVM як бекенду[5]. У 2011 році новий компілятор успішно скомпілював сам себе[6].

Перший стабільний випуск мови Rust 1.0 відбувся 15 травня 2015[7] після п'яти років розробки, він ознаменував повну стабілізацію програмних інтерфейсів усіх бібліотек і мовних конструкцій. В процесі підготовки гілки Rust 1.0 програмних інтерфейсів і можливості мови піддалися значній ревізії, після якої за умовчанням залишені тільки повністю готові до застосування можливості, реалізація яких не змінюватиметься надалі. Усі інші функції переведені в розряд експериментальних і винесені з постачання за умовчанням.

Паралельно компанія Samsung розвиває експериментальний браузерний рушій Servo, написаний мовою Rust з підтримкою багатонитевового рендеринга веб-сторінок і розпаралелюванням операцій з DOM (Document Object Model).

Огляд[ред.ред. код]

За структурою мова Rust нагадує C++, але істотно відрізняється в деяких деталях реалізації синтаксису і семантики, а також орієнтацією на блокову організацію структури коду, яка дозволяє реалізувати завдання у вигляді легковагих співпрограм. Автоматичне управління пам'яттю позбавляє розробника від маніпулювання вказівниками і захищає від проблем, що виникають через низькорівневу роботу з пам'яттю, таких як звернення до області пам'яті після її звільнення, розіменовування нульових вказівників, вихід за межі буфера тощо. Rust підтримує суміш імперативних процедурних і об'єктно-орієнтованих методів з такими парадигмами, як функційне програмування і модель акторів, а також узагальнене програмування і метапрограмування, в статичних і динамічних стилях.

Особливості[ред.ред. код]

Базові можливості мови:

Орієнтація на безпеку
  • Акуратна робота з пам'яттю — ніяких нульових і втрачених вказівників. Автоматичне управління пам'яттю;
  • Контроль мінливості. Об'єкти незмінні (Immutable) за умовчанням;
  • Безпека динамічного виконання: обробка збоїв, винятки, ведення логу, RAII/dtors;
  • Typestate: можливість визначення складних інваріантів, що контролюють структури даних.
Орієнтація на паралельність і ефективність коду
  • Явний контроль пам'яті, контролювання схеми розподілу пам'яті;
  • Вкрай легкі завдання, що формуються у вигляді співпрограми. Легкість в породження тисяч і мільйонів підпроцесів;
  • Ітератори стека (фактично лямбда-блоки без розподілу купи);
  • Статична, нативна компіляція із створенням виконуваних файлів ELF, PE, Mach-o;
  • Прямий і простий інтерфейс для коду на мові Сі;
Орієнтація на практичне застосування
  • Мультипарадигмальний, функціональний, імперативно-процедурний, об'єктно-орієнтована, підтримка паралельної actor-моделі;
  • Функції вищого порядку із зв'язуванням (біндінгами);
  • Немає номінальних типів або ієрархії типів;
  • Мульти-платформовий, підтримується Windows, Linux, Mac OS X, *BSD;
  • Зберігання рядків у UTF8, різноманітність низькорівневих типів;
  • Працює з існуючими нативними наборами інструментів: GDB, Valgrind, Shark тощо;
  • Практична можливість порушення правил: можливість ігнорування правил безпеки, якщо чітко вказано, коли і як їх порушувати.

Приклади[ред.ред. код]

Наведені нижче приклади є робочими при складанні за допомогою стабільної версії компілятора Rust 1.0.0.

Hello world:

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


Три версії реалізації функції пошуку факторіала, в рекурсивному та ітеративному стилях:

// The branches in this function exhibit Rust's optional implicit return
// values, which can be utilized where a more "functional" style is preferred.
// Unlike C++ and related languages, Rust's `if` construct is an expression
// rather than a statement, and thus has a return value of its own.
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 унікальних розумних вказівників, разом з тип-сумами[en] та методами:

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.
}

Виноски[ред.ред. код]

  1. COPYRIGHT. Rust compiler source repository. Процитовано 2012-12-17. 
  2. The Rust Language. Lambda the Ultimate. 2010-07-08. Архів оригіналу за 2012-11-23. Процитовано 2010-10-30. 
  3. Project FAQ. 2010-09-14. Процитовано 2012-04-17. 
  4. Future Tense. 2011-04-29. Архів оригіналу за 2012-09-18. Процитовано 2012-04-17. «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.» 
  5. Hoare, Graydon (2010-10-02). Rust Progress. Архів оригіналу за 2012-09-18. Процитовано 2012-04-17. 
  6. Hoare, Graydon (2011-04-20). [rust-dev] stage1/rustc builds. Процитовано 2012-04-17. «After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :)» 
  7. Announcing Rust 1.0

Посилання[ред.ред. код]