cheats.rs

repository·master·Indexed 26 days ago

https://github.com/ralfbiedert/cheats.rs

A high-density, single-page Rust language cheat sheet designed for quick lookup, discovery of language features, and learning Rust for experienced programmers. It covers core constructs including data structures, mutability, references, lifetimes, traits, async/await, closures, unsafe code, and control flow.

Tokens
26.5K
Snippets
32
Records
164
Agent score
88%

What's inside cheats.rs

  1. Understand Type Conversions in Rust

    master

    Rust provides several ways to obtain a type B from a type A. These methods range from trivial identity to complex automatic conversions like coercions and subtyping.

    Methods include:

    • Identity: B is exactly A.
    • Computation: Writing code to transform data from A to B.
    • Casts: On-demand conversion using the as keyword (use with caution).
    • Coercions: Automatic conversion within a 'weakening ruleset' (e.g., converting a mutable reference to an immutable one).
    • Subtyping: Automatic conversion within a 'same-layout-different-lifetimes ruleset'.
  2. Understand Atomics and Cache Coherence

    master

    Modern CPUs interact with memory through caches rather than accessing RAM directly. Each CPU has its own cache, which is significantly faster but smaller than main memory. Caches operate in cache lines (windows of bytes) and use protocols like MESI to track whether a line is Exclusive (E), Shared (S), or Modified (M).

    To ensure coherence (making sure data is seen consistently across all CPUs), caches communicate with each other. While this ensures data integrity, it can cause CPU stalls if multiple CPUs attempt to access or modify the same data simultaneously.

  3. Access Rust ecosystem resources and documentation

    master

    The following services are useful for working with the Rust language:

    • Rust Playground: Try and share snippets of Rust code.
    • crates.io: The central registry for all 3rd party libraries for Rust.
    • lib.rs: An unofficial overview of quality Rust libraries and applications.
    • blessed.rs: An unofficial, opinionated guide to the Rust ecosystem.
    • std.rs: Shortcut to the standard library (std) documentation.
    • stdrs.dev: Shortcut to std documentation including compiler-internal modules.
    • docs.rs: Documentation for 3rd party libraries, automatically generated from source.
    • releases.rs: Release notes for previous and upcoming versions.
  4. Understand Rust lifetime kinds and generics

    master

    While Rust does not explicitly use the term "kinds," understanding them helps clarify how generics and lifetimes work:

    • Values have types (e.g., true: bool).
    • Types have kinds (e.g., bool: *, where * is the kind for types).
    • Type Constructors (like Vec) take a type of kind * and produce a new type of kind * (e.g., Vec: * -> *).
    • Lifetimes are a specific kind. A type like S<'a> where S is a struct taking a lifetime parameter has the kind lifetime -> *.

    Note: Attempting to use a lifetime where a type is expected (e.g., Vec<'static>) will result in a kind error because Vec expects a type of kind *, not a lifetime.

  5. Understand Type Constructors vs Concrete Types

    master

    A type constructor (like Vec<>) is a template or recipe used to create concrete types. It does not occupy memory and cannot be translated directly to code until it is parameterized with a concrete type.

    • Vec<u8> is a concrete type (a vector of bytes).
    • Vec<> is a type constructor.
    • Vec<T> uses a generic parameter T as a variable name for a type that the user plugs in later.
  6. Understand Rust Application Memory Segments

    master

    At a low level, application memory is an array of bytes segmented by the operating environment into several key areas:

    • stack: Small, low-overhead memory where most local variables reside. It is managed by taking bytes when needed and discarding them when the scope is exited.
    • heap: Large, flexible memory used for dynamic allocation. Access is typically managed via stack proxies like Box<T>.
    • static: A resting place for long-lived data, such as the string part of a &str.
    • code: The area where the bitcode of your functions resides.
  7. Understand the Rust Abstract Machine

    master

    Rust operates on an Abstract Machine (AM) rather than targeting the CPU directly. The AM acts as a computing model abstraction and a contract between the developer and the compiler.

    Key characteristics of the Abstract Machine:

    • It is not a runtime and has no runtime overhead.
    • It defines memory regions (like the stack) and execution semantics.
    • It allows the compiler to perform optimizations by exploiting concepts the physical CPU might not recognize.
    • Violating the AM contract (e.g., through unsafe code) results in undefined behavior, where the optimizer may produce results that differ entirely from what the physical CPU would do.
  8. Install Rustup components

    master

    You can add additional tooling via rustup. Use the following commands to install common components:

    • cargo clippy: Lints for common API misuses and unidiomatic code.
    • cargo fmt: Automatic code formatter (requires rustup component add rustfmt).
    rustup component add rustfmt
  9. Understand the Call Stack and Function Boundaries

    master

    When a function is called, memory for parameters and return values is reserved on the stack. Before a function is invoked, the value is moved to an agreed-upon location on the stack, where it acts as a local variable within the function scope.

    Stack Frame behavior:

    • Function Calls: Calling a function extends the stack frame.
    • Recursion: Recursive calls continue to extend the stack. Unbounded recursion can lead to a stack overflow, which terminates the application.
    • Memory Repurposing: The stack can repurpose memory locations that previously held a certain type for new types (e.g., after a function returns or a variable is replaced).
  10. Use Raw Pointers for Unsafe Operations

    master

    Raw pointers (e.g., *const S or *mut S) differ from references because they provide almost no safety guarantees.

    • They may point to invalid or non-existent memory.
    • Dereferencing a raw pointer is always an unsafe operation.
    • Treating an invalid pointer as valid results in undefined behavior.
  11. Avoid Arithmetic Pitfalls in Rust

    master

    Be mindful of how arithmetic operations behave in Debug vs Release modes and with different types:

    OperationResultNote
    200_u8 / 0_u8Compile error-
    200_u8 / _0 (Debug)PanicDivision by zero panics in debug mode.
    200_u8 + 200_u8Compile error-
    200_u8 + _200 (Debug)PanicConsider checked_add, wrapping_add, etc.
    200_u8 + _200 (Release)144Overflows in release mode.
    -128_i8 * -1Compile errorWould overflow (128 does not fit in i8).
    -128_i8 * _1neg (Debug)Panic-
    -128_i8 * _1neg (Release)-128Overflows back to -128 in release mode.
    1_u8 / 2_u80Integer division truncates.
    0.8_f32 + 0.1_f320.90000004Floating point precision limits.
    1.0_f32 / 0.0_f32f32::INFINITY-
    0.0_f32 / 0.0_f32f32::NAN-
    x < f32::NANfalseNAN comparisons always return false.
    f32::NAN == f32::NANfalseUse f32::is_nan() instead.