Rust: взгляд старого программиста

Так сложились обстоятельства, что у меня возник перерыв в работе, в который я решил переключиться на Rust. Название этого языка резонировало с моим настроением, нашло отклик в душе.

Установка

Как это и бывает с большинством новых инструментов и фреймворков, их установка в основном была простой. Вот только и проходит она с большинством программ не так просто, как должна. Небеспроблемными были на моем верном ноутбуке Windows Surface 3:

  • настройка VSCode;
  • настройка пакета инструментальных средств.

Настройка VSCode была довольно простой на самом деле: нашел плагин и установил, ничего больше. Остальное  —  это настройка задач, с которой хорошо знающему VSCode реально разобраться самостоятельно.

О настройке пакета инструментальных средств сообщалось в документах по установке, но четкого объяснения там не было. В конце концов, я зашел на этот сайт для загрузки и запуска выбранных пакетов инструментальных средств C++ 2019 для установки. С их помощью исправляются ошибки компоновщика при наличии таковых.

Написание кода и запуск

Думаю, универсального диспетчера пакетов не существует, поэтому у каждого инструмента он свой. В Rust он называется Cargo. Для создания новых пакетов здесь надо ввести команду cargo new HelloWorld, для компилирования  —  команду cargo build, а для запуска (подождите-ка, вспомню)  —  cargo run.

Для запуска сборки нажимайте на ctrl-shift-b, но в нашем случае она не удалась

Здорово, что здесь есть команда new для совсем минимального формирования шаблонов (и оно действительно минимальное): с расширением VS Code задачи уже настроены для сборки, проверки и запуска.

Написание простого кода

Как обычно, начинаю с написания Hello World (и кто это придумал, Керниган и Ричи? По крайней мере, в «Википедии» так написано!). Затем я написал код по тому, что когда-то было самым популярным вопросом на собеседованиях, а именно написание Фибоначчиевого генератора рекурсивно:

20 лет назад я получил работу, написав именно это решение. Это было еще до того, как Фибоначчи обрел такую популярность, что код по нему мог написать даже ребенок…

При написании этого кода я узнал: 1) как объявлять параметры и возвращать типы; 2) что в Rust не допускается заключать в скобки условия if; 3) что println() работает, как большинство операторов печати.

Затем я подумал, что неплохо было бы посмотреть, есть ли здесь оптимизация хвостового вызова. Для этого попробовал переписать Фибоначчи в хвостовую рекурсию. Не то чтобы это было так необходимо, просто взяло верх мое стариковское любопытство. Для удаления хвостовым вызовом стековых кадров, он должен содержать все параметры в самой функции хвостового вызова. Я собирался также сделать версию с мемоизацией, но похоже, что кеш/мемоизация еще не встроены в базовые средства языка Rust.

Обратите внимание: в версии с оптимизацией хвостового вызова Фибоначчи (50) выполняется за 1 мс, в то время как у версии без нее на это уходит аж целых 279 секунд

Другие функциональные возможности языка + мои комментарии

Rust  —  статически типизированный язык, причем это язык со строгой типизацией (думаю, что сделать его таким было мудрым решением).

Здесь поддерживаются внутренние функции (такие как моя функция inner_fib, для которой используется двухпроходной компилятор). Так что опережающее объявление имеет место быть.

Здесь обязательно ставить в конце точки с запятой, за исключением операторов return, что немного странно. Для программиста, написавшего много кода на Python, эти точки с запятой не более чем лишние нажатия клавиш.

Здесь нет цикла «чтение  —  вычисление  —  вывод» для быстрого тестирования фрагментов кода, зато есть возможность установить сторонний вычислитель. Не уверен, насколько хорошо он будет тут работать, ведь фактически Rust  —  компилируемый язык.

Здесь поддерживаются функции высшего порядка как приятный элемент языка функционального программирования.

Похоже, в Rust имеется довольно обширный список функциональных возможностей, надежная библиотека (я с легкостью нашел и использовал функции измерения выполнения кода) и хорошая документация. Не уверен, люблю ли я этот язык, как все остальные, но пока в нем, кажется, есть толк! Возможно, я напишу продолжение после того, как использую Rust еще чуть больше, не ограничившись простым вычислением чисел Фибоначчи.

use std::time::{Instant};

fn main() {
    let n = 50;
    println!("Hello, world lets run fib tests for size: {}", n);
    let start = Instant::now();
    println!("Hello fibtail: {}",fib2(n));
    let duration = start.elapsed();
    println!("--->fibtail perf: {:?}",duration);

    let start = Instant::now();
    println!("Hello fib: {}",fib(n));
    let duration = start.elapsed();
    println!("--->fibt perf: {:?}",duration);
}

fn fib(n: i64) -> i64 {
    if n == 0 { return 0;}
    if n == 1 { return 1;}
    return fib (n-1) + fib(n-2);
}

fn fib2(n: i64) -> i64 {
    fn fib2_inner(a: i64, b:i64, n:i64) -> i64 {
        if n == 0 { return a;}
        return fib2_inner(b, a+b, n-1)
    }
    return fib2_inner(0, 1, n)
}

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Doug Foo: Rust for Old People

Предыдущая статьяПостроение бесконечного списка с помощью SwiftUI и Combine
Следующая статьяВизуализация стратегии автоматизированного тестирования