Изучение небезопасных операций в Rust

RustRustBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

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

Примечание: Если лаб не уточняет имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать main.rs, скомпилировать и запустить его с помощью rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/constants_usage("Constants Usage") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/unsafe_rust("Unsafe Rust") subgraph Lab Skills rust/variable_declarations -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/constants_usage -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/integer_types -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/function_syntax -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/expressions_statements -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/method_syntax -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} rust/unsafe_rust -.-> lab-99286{{"Изучение небезопасных операций в Rust"}} end

Небезопасные операции

В качестве введения в этот раздел, чтобы цитировать официальную документацию, "следует стараться минимизировать количество небезопасного кода в кодовой базе". С этим в виду, давайте начнем! Небезопасные аннотации в Rust используются для обхода защит, установленных компилятором; конкретно, unsafe используется для четырех основных вещей:

  • разыменовывание сырых указателей
  • вызов функций или методов, которые являются небезопасными (в том числе вызов функции через FFI, см. [предыдущую главу книги)
  • доступ к или модификация статических изменяемых переменных
  • реализация небезопасных трейтов

Сырые указатели

Сырые указатели * и ссылки &T работают аналогично, но ссылки всегда безопасны, потому что гарантируется, что они указывают на валидные данные из-за проверщика заимствования. Разыменование сырого указателя можно сделать только через небезопасный блок.

fn main() {
    let raw_p: *const u32 = &10;

    unsafe {
        assert!(*raw_p == 10);
    }
}

Вызов небезопасных функций

Некоторые функции могут быть объявлены как небезопасные, что означает, что ответственность за обеспечение правильности ложится на программиста, а не на компилятор. Одним примером является [std::slice::from_raw_parts], которая создаст срез, зная указатель на первый элемент и длину.

use std::slice;

fn main() {
    let some_vector = vec![1, 2, 3, 4];

    let pointer = some_vector.as_ptr();
    let length = some_vector.len();

    unsafe {
        let my_slice: &[u32] = slice::from_raw_parts(pointer, length);

        assert_eq!(some_vector.as_slice(), my_slice);
    }
}

Для slice::from_raw_parts одно из предположений, которое должно быть соблюдено, заключается в том, что указатель, переданный в функцию, указывает на валидную память и что память, на которую он указывает, имеет правильный тип. Если эти инварианты не соблюдаются, то поведение программы не определено и невозможно预知ить, что произойдет.

Резюме

Поздравляем! Вы завершили лабу по Небезопасным операциям. Вы можете практиковаться в более лабах в LabEx, чтобы улучшить свои навыки.