🦀 Rust для начинающих: почему этот язык пугает и почему его стоит выучить


На главную > Блог > Категория > 🦀 Rust для начинающих: почему этот язык пугает и почему его стоит выучить

rust

Вступление: Rust — язык, который не даст вам выстрелить себе в ногу

Если вы когда-нибудь писали на C или C++, вы знаете эту боль: программа скомпилировалась, запустилась, работает… а потом через 10 минут падает с ошибкой сегментации. Вы ищете баг три часа, а оказывается, вы забыли очистить память или обратились к нулевому указателю. Rust решает эти проблемы на уровне компилятора. Он не даст вам выстрелить себе в ногу — не потому что он «злой», а потому что он заставляет вас думать о безопасности памяти с самого начала.

В этой статье я расскажу, что такое Rust, почему его называют «самым любимым языком программирования» уже 7 лет подряд (по опросам Stack Overflow), и покажу основы на практических примерах. Без занудства, но с погружением в детали. Подходит даже тем, кто последний раз программировал в школе на Pascal.

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

1. Что такое Rust и зачем он нужен (особенно трейдерам)

Rust — это системный язык программирования, разработанный компанией Mozilla в 2010 году. Его главные фишки:

  • Скорость C++ — Rust компилируется в машинный код, не имеет сборщика мусора, работает на металле.
  • 🛡️ Безопасность памяти — никаких segfaults, утечек памяти, гонок данных. Компилятор проверяет всё сам.
  • 🧵 Безопасное многопоточное программирование — Rust не позволит вам создать состояние гонки (data race) на этапе компиляции.
  • 📦 Отличная экосистема — менеджер пакетов Cargo, огромная библиотека крейтов (crates.io).
📊 Почему Rust интересен трейдерам?
Высокочастотная торговля (HFT), боты на криптобиржах, обработка потоковых данных — всё это требует скорости и надёжности. Python хорош для прототипов, но для продакшена на высоких скоростях Rust становится идеальным выбором. Многие HFT-фонды уже переходят с C++ на Rust.

2. Установка и первая программа (традиционный Hello, World!)

Rust устанавливается через rustup — официальный инструмент управления версиями.

Установка на Windows, Mac, Linux:

  
# Перейдите на сайт rustup.rs и скачайте установщик
# Или выполните в терминале (Mac/Linux):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# После установки проверьте версию:
rustc --version
cargo --version

Создаём первый проект с помощью Cargo:


cargo new hello_rust
cd hello_rust
cargo run

Вы увидите:

Compiling hello_rust v0.1.0
    Finished dev [unoptimized + debuginfo] target(s)
     Running `target/debug/hello_rust`
Hello, world!

Поздравляю, вы только что написали и запустили свою первую программу на Rust. Файл src/main.rs выглядит так:


fn main() {
    println!("Hello, world!");
}
📦 Что такое Cargo? Это менеджер пакетов и система сборки, как pip + setuptools для Python, только мощнее и удобнее. Cargo создаёт проект, скачивает зависимости, компилирует и запускает тесты одной командой.

3. Основы синтаксиса: переменные, типы данных, функции

Переменные и неизменяемость (ключевая фишка Rust)

По умолчанию все переменные в Rust неизменяемые (immutable). Это значит, что вы не можете изменить их значение после присвоения. Это одна из главных причин безопасности Rust.


 fn main() {
    let x = 5;       // неизменяемая переменная
    // x = 6;        // ошибка компиляции! нельзя изменить
    
    let mut y = 10;  // mut = mutable (изменяемая)
    y = 11;          // так можно
    
    println!("x = {}, y = {}", x, y);
}

Типы данных

Rust — статически типизированный язык, но компилятор часто выводит типы сам.


fn main() {
    // Целые числа
    let a: i32 = -42;    // 32-битное целое со знаком
    let b: u64 = 100;    // 64-битное беззнаковое
    let c = 255;         // компилятор выведет i32
    
    // Числа с плавающей точкой
    let d: f64 = 3.14159;
    
    // Булевый тип
    let e: bool = true;
    
    // Символы (Unicode)
    let f: char = '🦀';   // да, краб — символ!
    
    println!("{} {} {} {} {} {}", a, b, c, d, e, f);
}

Функции


fn add(x: i32, y: i32) -> i32 {
    x + y   // последнее выражение возвращается (без точки с запятой!)
}

fn main() {
    let sum = add(5, 7);
    println!("Сумма: {}", sum);
}
🎯 Обратите внимание: В Rust нет ключевого слова return для последнего выражения. Если поставить точку с запятой, выражение не вернётся, а превратится в оператор. Это частая ошибка новичков.

4. Владение (Ownership) — сердце Rust и главная боль новичков

Система владения — это то, что отличает Rust от всех остальных языков. Она позволяет управлять памятью без сборщика мусора и без ручного освобождения. Три правила:

  1. Каждое значение в Rust имеет владельца (owner).
  2. В одно время может быть только один владелец.
  3. Когда владелец выходит из области видимости, значение удаляется (освобождается память).

Пример с перемещением (move):


fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // s1 перемещается в s2
    
    // println!("{}", s1); // ошибка! s1 больше не владеет значением
    println!("{}", s2); // работает
}

Если нужно скопировать, а не переместить:


fn main() {
    let s1 = String::from("hello");
    let s2 = s1.clone();  // теперь два независимых значения
    
    println!("s1 = {}, s2 = {}", s1, s2); // работает
}
⚠️ Важное предупреждение: Система владения поначалу бесит. Вы будете получать ошибки компилятора «cannot use value after move». Это нормально. Через пару недель вы начнёте думать о владении автоматически.

5. Заимствование (Borrowing) — как пользоваться значением, не забирая владение

Чтобы не перемещать значение туда-сюда, Rust предлагает ссылки (&). Это называется «заимствование».


fn calculate_length(s: &String) -> usize {  // s — это ссылка
    s.len()
} // здесь s выходит из области видимости, но так как он не владеет значением,
  // ничего не удаляется

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);  // передаём ссылку, а не владение
    
    println!("Длина '{}' = {}", s1, len);
}

Изменяемые ссылки (mutable references):


fn change(s: &mut String) {
    s.push_str(", world");
}

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);  // "hello, world"
}
🎯 Правило одного изменяемого заимствования: В Rust нельзя иметь две изменяемые ссылки на одно значение одновременно. Это предотвращает гонки данных на этапе компиляции.

6. Option и Result: вместо null и исключений

В Rust нет null. Вместо этого есть Option<T> для случаев, когда значение может отсутствовать, и Result<T, E> для обработки ошибок.

Option


fn divide(numerator: f64, denominator: f64) -> Option<f64> {
    if denominator == 0.0 {
        None
    } else {
        Some(numerator / denominator)
    }
}

fn main() {
    match divide(10.0, 2.0) {
        Some(result) => println!("Результат: {}", result),
        None => println!("На ноль делить нельзя!"),
    }
    
    // Или коротко с unwrap (осторожно!)
    let res = divide(10.0, 2.0).unwrap(); // если None — программа упадёт
}

Result


use std::fs::File;

fn main() {
    let file = File::open("hello.txt");
    
    let file = match file {
        Ok(f) => f,
        Err(error) => panic!("Не удалось открыть файл: {:?}", error),
    };
}

7. Практический пример: парсинг котировок из CSV

Напишем небольшую программу, которая читает CSV-файл с котировками и выводит среднюю цену. Это полезно для трейдерских задач.

  
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    // Открываем файл
    let file = File::open("quotes.csv").expect("Не удалось открыть файл");
    let reader = BufReader::new(file);
    
    let mut total = 0.0;
    let mut count = 0;
    
    for line in reader.lines() {
        let line = line.expect("Ошибка чтения строки");
        let parts: Vec<&str> = line.split(',').collect();
        
        // Предполагаем, что цена во второй колонке
        if parts.len() >= 2 {
            if let Ok(price) = parts[1].trim().parse::() {
                total += price;
                count += 1;
            }
        }
    }
    
    if count > 0 {
        let average = total / count as f64;
        println!("Средняя цена: {:.2}", average);
    } else {
        println!("Нет данных");
    }
}
📈 Как запустить: создайте файл quotes.csv с котировками, например:
2025-01-01,68000
2025-01-02,68500
2025-01-03,67200
И выполните cargo run.

Заключение: Rust — сложный, но благодарный путь

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

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

Начните с малого: установите Rust, напишите «Hello, world», поиграйте с переменными и ссылками. Ошибки компиляции — это не враги, а учителя. Читайте их внимательно. Через месяц вы удивитесь, как быстро привыкаешь к дисциплине Rust.

И помните: даже если вы не станете профессиональным Rust-разработчиком, понимание владения и заимствования сделает вас лучшим программистом на любом другом языке.

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

 

Дата размещения статьи: 2026-05-24T11:23:50