Rust Programming

126 flashcards by MentisLibrary

Ownership, borrowing and lifetimes first, then traits and generics, enums and pattern matching, error handling with Result, iterators, smart pointers, fearless concurrency, and working with Cargo.

What does let declare when mut is left off?
An immutable binding: assigning to it again is a compile error. Add mut to allow reassignment.
What is shadowing?
Declaring a new variable with let using an existing name; the new binding hides the old one and may have a different type.
Name Rust's integer types and the default for an unsuffixed literal.
Signed i8, i16, i32, i64, i128, unsigned u8 through u128, plus pointer-sized isize and usize. An unsuffixed integer literal defaults to i32.
What is the unit type ()?
The empty tuple: the type of expressions that produce no value, such as a function with no return type or a block ending in a semicolon.
String vs &str
String is an owned, growable, heap-allocated UTF-8 buffer. &str is a borrowed view (pointer plus length) into UTF-8 text, such as a literal or a slice of a String.
State the three ownership rules.
Each value has exactly one owner; there is only one owner at a time; when the owner goes out of scope the value is dropped.
What is a move?
Assigning or passing a non-Copy value transfers ownership; the original binding becomes invalid and using it is a compile error.
Copy vs Clone
Clone is an explicit, possibly expensive duplicate made with .clone(). Copy is an implicit bitwise copy for simple types and is a marker subtrait of Clone.
What does borrowing mean?
Taking a reference (&T or &mut T) to a value without taking ownership. The owner keeps the value and the reference must not outlive it.
State the aliasing rule for references.
At any moment a value may have either any number of shared references &T or exactly one mutable reference &mut T, never both.
What is a slice?
A reference to a contiguous range of a collection, written &[T] or &str, storing a pointer and a length.
What is a lifetime?
A compile-time name for the scope during which a reference is valid. Annotations such as 'a relate the lifetimes of inputs and outputs so the borrow checker can verify them.
When can lifetime annotations be omitted?
Under the elision rules: each reference parameter gets its own lifetime; if there is exactly one input lifetime it is assigned to all outputs; if there is a &self or &mut self, its lifetime goes to the outputs.
What does 'static mean?
The lifetime of the whole program. String literals are &'static str, and a T: 'static bound means the type holds no non-static references (owned data qualifies).
How do you define a struct and create an instance?
struct Name { field: Type }, then Name { field: value }. Field-init shorthand fills a field from a same-named variable.
What does struct update syntax ..other do?
Fills every field you did not list from another instance of the same struct.
What is a tuple struct?
A struct with unnamed positional fields, such as struct Meters(f64);, accessed with .0, .1 and so on.
What is an enum in Rust?
A type with a fixed set of variants, each of which may carry data of a different shape (a tagged union).
What is Option<T>?
An enum with variants Some(T) and None, Rust's replacement for null.
What is Result<T, E>?
An enum with Ok(T) for success and Err(E) for failure, used for recoverable errors instead of exceptions.
What happens if a match misses a variant?
Compile error. A match must be exhaustive: every possible value is covered, or a wildcard _ arm ends it.
When would you use if let instead of match?
When you care about one pattern only. if let is sugar for a match with a single arm and an optional else.
What does let else do?
Binds a refutable pattern, or runs the else block which must diverge (return, break, continue or panic). Stable since Rust 1.65.
What does the ? operator do?
On a Result, returns early with Err(e.into()) when the value is an error, otherwise unwraps the Ok. On an Option it returns None early.
unwrap vs expect
Both return the inner value or panic; expect(msg) prints your message in the panic, which makes the failure far easier to diagnose.
How do you supply a fallback for an Option without panicking?
unwrap_or(v) for a ready value, unwrap_or_else(|| compute()) for one computed only when needed, unwrap_or_default() for the type's Default.
map vs and_then on Option and Result
map transforms the inner value with a plain function. and_then chains a function that itself returns an Option or Result, flattening the nesting.
When should code panic instead of returning a Result?
Panic for bugs and broken invariants in code you control; return Result for expected failures such as a missing file, bad input or a network error.
What is Box<dyn Error> used for?
A heap-allocated trait object that can hold any error implementing std::error::Error, handy in applications that only need to propagate and print errors.
How does ? convert one error type into another?
Through the From trait: ? calls From::from on the error, so implementing From<io::Error> for MyError lets ? convert automatically.