Skip to content

Instantly share code, notes, and snippets.

@vladak
Last active September 15, 2025 16:17
Show Gist options
  • Save vladak/f8f7ac1d48e4011e061ee0e06cabaf01 to your computer and use it in GitHub Desktop.
Save vladak/f8f7ac1d48e4011e061ee0e06cabaf01 to your computer and use it in GitHub Desktop.
Rust gotchas

Learning Rust gotchas

That is, learning from C99.

Basics

  • by default variables are constant. To make a variable mutable, it has to have the mut keyword:
    • otherwise it would not compile
fn main() {
    // also, type inferrence
    let mut foo = 'A';
    foo = 'b';
}
  • duplicate variable definitions get marked merely as unused variables:
fn main() {
  let foo = 1;
  let foo = 3;
}
  • The exclamation mark means this is a macro.
    • for printing there is also print! and eprint! and eprintln! (for stderr)
fn main() {
    println!("Hello, world!");
}
  • print macros have interpolation:
fn main() {
  let foo = "bar";
  println!("{}", foo);
  println!("{foo}"); // since some Rust version
}
  • the ability to use expressions within the {} seems to be limited (unlike in Python)
fn main() {
    let signs = "QRYZEPTGMk ";
    println!("{signs.len()}"); // fails to compile
    println!("{}", signs.len());
}
  • no semicolon at the end of a function means the value should be returned
fn main() {
    // there does not have to a semicolon for the last expression/statement in a block/function
    let x = println!("{}", 'A'.is_ascii_hexdigit())
}
  • there is 128-bit integer type:
fn main() {
    let mut foo:u128 = 2 << 68;
    while foo > 0 {
        // also, string interpolation
        println!("{foo}");
        foo = foo / 8;
    }
}
  • accessing a slice beyond outside index results in panic (due to the bound check):
fn main() {
    let signs = " TGMK";
    // also note that slice cannot be used directly on str (&signs[8]) cause of UTF-8
    let letter = &signs.as_bytes()[8];
 }
  • sliced str (string type) has to be dereferenced and casted to get a printable char:
fn main() {
    let signs = "TGMK ";
    let letter = &signs.as_bytes()[0];
    println!("letter '{}'", *letter as char);
}

Build

  • rustc is the low-level compiler utility, cargo is the high-level (make/dependencies)

    • cargo run, cargo build, cargo clean
  • there is no macro language per se like in C, however portions of code can be compiled based on flags

# Cargo.toml

[features]
my_feature = []
    #[cfg(feature = "my_feature")]
    {
        println!("count = {count}");
        print!("{foo} ");
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment