Перейти к содержанию

Перегрузка кода Rust - магия умных указателей

Posted on:4 июля 2023 г. at 09:16

Example Dynamic OG Image link Умные указатели предлагают множество преимуществ по сравнению с обычными указателями. Эта статья научит вас всему, что вам нужно знать об умных указателях в Rust.

Одним из сильных преимуществ Rust является управление памятью, особенно потому, что безопасность не нарушена.

Структура владения Rust помогает компилятору гарантировать безопасность кода и отсутствуют проблемы с памятью, такие как висячие указатели и утечка памяти.

В дополнение к обычным указателям, Rust поддерживает умные указатели с дополнительными метаданными и возможностями.

Умные указатели полезны для устранения утечек памяти.

Что такое умные указатели в Rust?

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

Поскольку Rust использует структуры для выполнения умных указателей, можно также и управлять умными указателями.

При соединении памяти с помощью умных указателей с динамически выделенными данными память автоматически освобождается.

Умные указатели предоставляют возможности ограничения срока службы объектов Rust, что делает их полезными для устранения ошибок, таких как обособление нулевых указателей и утечки памяти, которые распространены в других низкоуровневых языках, таких как C и C++.

Преимущества использования умных указателей

Ниже приведены некоторые преимущества использования умных указателей:

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

Типы умных указателей

Rust поддерживает множество умных указателей, включая Box, Rc, RefCell и Mutex.

1. Box

Box - самый основной и часто используемый умный указатель Rust.

Box помогает с выделением памяти и создает штучный указатель для специальных возможностей.

Если необходимо гарантировать, что память немедленно освобождается, когда указатели находятся вне области действия, то полезен Box.

Чтобы создать и использовать указатель Box, выполните следующие действия.

// новый экземпляр box указателя
let x = Box::new(5);
println!(x)

Поскольку тип Box является частью прелюдии Rust, импортировать его, в отличие от других умных указателей, не потребуется.

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

2. RC

Умный указатель RC (Reference Counted) позволяет создавать общие значения владения.

RC отслеживают количество ссылок на значение и освобождают его, когда конечная ссылка становится недействительной.

При необходимости совместного владения переменной для обеспечения доступности во многих частях программы используется RC.

Импортируйте структуру RC из стандартной библиотеки, создайте новый RC-указатель с помощью new функции, затем клонируйте переменную указателя с переменной, чтобы использовать RC указатель.

use std::rc::Rc;

fn main() {

    // новый экземпляр указателя RC
    let x = Rc::new(5);
    let y = Rc::clone(&x);

    println!("x = {}, y = {}", x, y);
}

Переменная x является переменной указателя RC, а переменная y является клоном с доступом к памяти.

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

3. RefCell

Внутренняя изменяемость указателя RefCell позволяет неизменяемым и изменяемым ссылкам сосуществовать до тех пор, пока существует только одна изменяемая ссылка в любой момент.

При изменении данных, принадлежащих изменяемым ссылкам, используется RefCell.

Поскольку метод Refcell отсутствует в прелюдии Rust, для использования необходимо импортировать структуру из стандартной библиотеки.

use std::cell::RefCell;

fn main(){

    //новый экземпляр указателя Refcell
    let x = RefCell::new(5);

    let y = x.borrow();
    let z = x.borrow_mut();

    println!("y = {}", *y);
    println!("z = {}", *z);

Значение сохраняется в указателе Refcell, а переменная y является неизменяемой ссылкой на значение.

Функция borrow_mut преобразует значение в изменяемую ссылку.

Если есть только одна изменяемая ссылка, программа безопасна.

4. Mutex

Взаимные исключения предлагаются через указатель Mutex.

В параллельных программах интеллектуальный указатель Mutex полезен для синхронизации доступа к значениям сразу для нескольких потоков.

Mutex использует взаимное исключение, чтобы гарантировать, что только один поток может получить доступ к значению одновременно, не допуская гонки данных.

Чтобы использовать Mutex в Rust, импортируйте структуру Mutex и создайте новый экземпляр.

use std::sync::Mutex;

fn main() {

    // новый экземпляр указателя mutex
    let counter = Mutex::new(0);

    {
        let mut num = counter.lock().unwrap();
        *num += 1;
    }

    println!("Result: {}", *counter.lock().unwrap());
}

Новый экземпляр Mutex представлен переменной counter.

Основная функция использует метод блокировки экземпляра Mutex для получения информации о блокировки Mutex.

Перед снятием блокировки и публикацией значения, блокировка обеспечивает безопасное изменение значения счетчика.

Тип Mutex позволяет одновременно использовать и изменять общие ресурсы (в данном случае переменную счетчика) только одному потоку.

Чтобы предотвратить гонку данных и другие трудности параллелизма, взаимное исключение гарантирует сериализацию параллельного доступа к общим ресурсам.

Модель владения Rust гарантирует безопасность памяти

Одним из методов безопасности и гибкости памяти Rust являются умные указатели.

С помощью средства проверки заимствования во время компиляции модель владения Rust гарантирует безопасный доступ программ к памяти.

Проверка заимствования является ключевым компонентом модели владения Rust, сохраняя строгие ограничения на доступ к памяти и изменения.