Explorando las Operaciones no Seguras de Rust

RustRustBeginner
Practicar Ahora

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

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, exploraremos las operaciones no seguras en Rust, que se utilizan para evitar las protecciones del compilador y se utilizan típicamente para desreferenciar punteros crudos, llamar a funciones no seguras, acceder o modificar variables estáticas mutables e implementar rasgos no seguros. Estas operaciones deben minimizarse en una base de código para garantizar la seguridad.

Nota: Si el laboratorio no especifica un nombre de archivo, puede utilizar cualquier nombre de archivo que desee. Por ejemplo, puede utilizar main.rs, compilar y ejecutarlo con 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{{"Explorando las Operaciones no Seguras de Rust"}} rust/constants_usage -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} rust/integer_types -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} rust/function_syntax -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} rust/expressions_statements -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} rust/method_syntax -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} rust/unsafe_rust -.-> lab-99286{{"Explorando las Operaciones no Seguras de Rust"}} end

Operaciones no seguras

Como introducción a esta sección, para citar las documentaciones oficiales, "uno debe tratar de minimizar la cantidad de código no seguro en una base de código". Con eso en mente, ¡empecemos! Las anotaciones no seguras en Rust se utilizan para evitar las protecciones establecidas por el compilador; específicamente, hay cuatro cosas principales para las que se utiliza lo no seguro:

  • Desreferenciar punteros crudos
  • Llamar a funciones o métodos que son unsafe (incluyendo llamar a una función a través de FFI, ver [un capítulo anterior del libro)
  • Acceder o modificar variables estáticas mutables
  • Implementar rasgos no seguros

Punteros crudos

Los punteros crudos * y las referencias &T funcionan de manera similar, pero las referencias siempre son seguras porque se garantiza que apunten a datos válidos debido al verificador de préstamos. La desreferencia de un puntero crudo solo se puede hacer a través de un bloque no seguro.

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

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

Llamar a funciones no seguras

Algunas funciones se pueden declarar como unsafe, lo que significa que es responsabilidad del programador garantizar la corrección en lugar de la del compilador. Un ejemplo de esto es [std::slice::from_raw_parts] que creará un segmento dado un puntero al primer elemento y una longitud.

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);
    }
}

Para slice::from_raw_parts, una de las suposiciones que debe mantenerse es que el puntero pasado apunte a una memoria válida y que la memoria apuntada sea del tipo correcto. Si estas invariantes no se mantienen, entonces el comportamiento del programa es indefinido y no se sabe lo que pasará.

Resumen

¡Felicidades! Has completado el laboratorio de Operaciones no seguras. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.