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

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
Rust
Rust programming language black logo.svg
Парадигма компільована, паралельна, функційна, імперативне, об'єктно-орієнтована, структурна
Дата появи 2010
Творці Graydon Hoare
Розробник Rust Project Developers
Останній реліз 1.43.1 (7 травня 2020; 9 місяців тому (2020-05-07))
Система типізації статична, 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мова програмування, яку розробляє Mozilla Research[2]. Мова має строгу типізацію[en] і сфокусована на безпечній роботі з пам'яттю і забезпеченні високого паралелізму виконання завдань (можливість породжувати тисячі і навіть мільйони підпроцесів).

Сирцевий код проекту поширюються під ліцензією 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[en], Шаблон:Mach-O;
  • Прямий і простий інтерфейс для коду на мові Сі;
Орієнтація на практичне застосування
  • Мультипарадигмальний, функціональний, імперативно-процедурний, об'єктно-орієнтована, підтримка паралельної actor-моделі;
  • Функції вищого порядку із зв'язуванням (біндінгами);
  • Немає номінальних типів або ієрархії типів;
  • Мульти-платформовий, підтримується Windows, Linux, Mac OS X, *BSD;
  • Зберігання рядків у UTF8, різноманітність низькорівневих типів;
  • Працює з існуючими нативними наборами інструментів: GDB, Valgrind, Shark тощо;
  • Практична можливість порушення правил: можливість ігнорування правил безпеки, якщо чітко вказано, коли і як їх порушувати.

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

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

Hello world:

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 унікальних розумних вказівників, разом з тип-сумами[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 (2014-06-07). Internet archaeology: the definitive, end-all source for why Rust is named "Rust". Reddit.com. Процитовано 2018-02-04. 
  6. Hoare, Graydon (2010-10-02). Rust Progress. Архів оригіналу за 2012-09-18. Процитовано 2012-04-17. 
  7. 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 :)» 
  8. Announcing Rust 1.0
  9. Samsung teams up with Mozilla to build browser engine for multicore machines. Ars Technica. Процитовано 2015-10-24. 

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