0Pricing
Learn Rust Coding · Lektion

Mit Unsafe Rust arbeiten

Verstehen Sie, wann und wie Sie `unsafe`-Blöcke verwenden, um die Sicherheitsprüfungen von Rust zu umgehen und FFI sowie hardwarenahe Speicheroperationen zu ermöglichen.

Mit Unsafe Rust arbeiten ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 3 von 3. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Learn Rust Coding-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Learn Rust Coding-Kurs umfasst insgesamt 3 Lektionen.

Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.

Unsafe Rust: An Introduction

Welcome to Unsafe Rust! While Rust is famous for its memory safety guarantees, there are specific scenarios where you might need to bypass some of these checks.

The unsafe keyword in Rust allows you to do just that. It's not a way to write 'bad' code, but rather a tool for advanced use cases where you need more direct control over memory or hardware.

The Five Unsafe Superpowers

When you use an unsafe block, you gain access to five special actions that the Rust compiler normally prevents:

  • Dereference raw pointers: Directly access memory addresses.
  • Call unsafe functions or methods: Execute functions with preconditions the compiler can't verify.
  • Implement unsafe traits: Declare that your type upholds specific invariants.
  • Access or modify mutable static variables: Share mutable state globally, risking data races.
  • Access fields of unions: Read from a union, which might be an invalid type for the current data.

Dereferencing Raw Pointers

Raw pointers are memory addresses without Rust's usual safety guarantees. You can create them from references (&T, &mut T) but dereferencing them requires an unsafe block.

This means you, the programmer, are responsible for ensuring the pointer is valid and points to allocated memory.

fn main() {
  let mut num = 5;
  let r1 = &num as *const i32; // Immutable raw pointer
  let r2 = &mut num as *mut i32; // Mutable raw pointer

  unsafe { // The `unsafe` block starts here
    println!("r1 points to: {}", *r1);
    *r2 = 10; // Modify data through mutable raw pointer
    println!("r2 points to: {}", *r2);
  } // The `unsafe` block ends here

  println!("Num is now: {}", num);
}

Calling Unsafe Functions

Some functions are marked as unsafe fn. This means the function has preconditions that the Rust compiler cannot guarantee. For instance, a function might expect a valid memory address, but cannot verify it.

Calling such functions must be wrapped in an unsafe block, indicating that you, the caller, ensure all preconditions are met.

unsafe fn dangerous_operation() {
  println!("This operation could be dangerous if preconditions aren't met!");
}

fn main() {
  println!("Attempting a dangerous operation...");
  unsafe { // Calling an unsafe function requires `unsafe`
    dangerous_operation();
  }
  println!("Operation completed.");
}

Mutable Static Variables

Rust prevents global mutable state by default to avoid data races. However, you can declare mutable static variables using static mut.

Accessing or modifying these variables is considered unsafe because multiple threads could try to access them simultaneously, leading to undefined behavior. Proper synchronization is your responsibility.

static mut COUNTER: i32 = 0; // A mutable static variable

fn add_to_counter(inc: i32) {
  unsafe { // Modifying `static mut` requires `unsafe`
    COUNTER += inc;
  }
}

fn main() {
  add_to_counter(5);
  unsafe { // Reading `static mut` also requires `unsafe`
    println!("COUNTER after first add: {}", COUNTER);
  }

  add_to_counter(10);
  unsafe {
    println!("COUNTER after second add: {}", COUNTER);
  }
}

Implementing Unsafe Traits

Some traits in Rust are marked as unsafe trait. This signifies that implementing them requires upholding certain invariants that the compiler cannot check.

A common example is the Send and Sync traits, which relate to thread safety. If you manually implement an unsafe trait, you must use unsafe impl Trait for Type and guarantee its safety properties.

For most beginners, you'll encounter this less frequently, as Rust often handles these automatically or via safe abstractions.

Accessing Union Fields

A union is a special type that can hold a value of *one* of its variants at any given time, but all variants share the same memory location. It's similar to C unions.

Accessing a field of a union requires an unsafe block because the compiler cannot know which field is currently active. Reading from an inactive field can lead to undefined behavior or misinterpretation of data.

union Data {
  integer: u32,
  float: f32,
}

fn main() {
  let mut d = Data { integer: 42 }; // Initialize with an integer

  unsafe {
    // Accessing 'integer' is safe here
    println!("Integer value: {}", d.integer);

    // Accessing 'float' is unsafe, as 'integer' was initialized.
    // This would interpret the integer's bits as a float.
    // println!("Float value (unsafe): {}", d.float);
  }

  d.float = 3.14; // Now initialize with a float
  unsafe {
    // Accessing 'float' is safe now
    println!("Float value: {}", d.float);
  }
}

Practical Unsafe Scenarios

While unsafe should be used sparingly, it's crucial for several advanced programming tasks:

  • Foreign Function Interface (FFI): Interacting with code written in other languages (like C/C++ libraries).
  • Performance Optimizations: Sometimes, bypassing Rust's checks can yield small performance gains in critical sections (but measure first!).
  • Low-level System Programming: Writing operating systems, device drivers, or embedded systems.
  • Building Safe Abstractions: Implementing safe data structures or APIs on top of unsafe primitives (e.g., how Vec is built).

Your Responsibility with Unsafe

When you use unsafe, you take on the responsibility of upholding Rust's safety guarantees manually. This means:

  • Ensuring memory is valid and correctly aligned.
  • Preventing data races when dealing with shared mutable state.
  • Avoiding dangling pointers or use-after-free errors.
  • Ensuring all function preconditions are met.

Misusing unsafe can lead to undefined behavior, which is the worst kind of bug and can be very hard to debug.

Unsafe Knowledge Check

Which of the following actions requires an unsafe block in Rust?

Recap: Unsafe Rust

You've learned about Unsafe Rust, a powerful feature that allows you to bypass some of Rust's compile-time safety checks for specific, advanced scenarios.

Remember that unsafe doesn't turn off the borrow checker completely, but it shifts the responsibility for memory safety and invariants entirely to you, the programmer. Use it judiciously and with extreme caution, typically for FFI, low-level optimizations, or building safe abstractions.

Häufig gestellte Fragen

Ist die Lektion „Mit Unsafe Rust arbeiten“ kostenlos?

Ja — der vollständige Text von „Mit Unsafe Rust arbeiten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Learn Rust Coding-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Learn Rust Coding-Kurs umfasst insgesamt 3 Lektionen.

Was lerne ich in „Mit Unsafe Rust arbeiten“?

Verstehen Sie, wann und wie Sie `unsafe`-Blöcke verwenden, um die Sicherheitsprüfungen von Rust zu umgehen und FFI sowie hardwarenahe Speicheroperationen zu ermöglichen. Du übst Learn Rust Coding mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Learn Rust Coding zu starten?

Keine Vorkenntnisse erforderlich. Learn Rust Coding auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 3.

Wie lange dauert die Lektion „Mit Unsafe Rust arbeiten“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Learn Rust Coding-Lektion Code schreiben und ausführen?

Ja. Jede Learn Rust Coding-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Deklarative Makros (`macro_rules!`)
  2. Prozedurale Makros: Derive, Function
  3. Mit Unsafe Rust arbeiten
← Zurück zu Learn Rust Coding