After a week of learning, I'm going to dedicate this blog article to reflecting on what we've learned so far. Before that though here are a few fun facts:
- The blog series has had over 300 views so far - so THANKS for that :)
- If you've read every article in the series, that's over 4500 words.
- Together we've asked and answered 30 questions about Rust.
To break from tradition, I won't be asking any questions today. Tomorrow I'll sketch out what I'm planning for the next week of the series 💪
Yesterday's questions answered
- All values are by default stack-allocated in Rust.
Boxis a way to tell the compiler to put a value on the heap. This makes aBoxa smart pointer. Values should be added to the heap when they are expected to grow or be shared of multiple threads. - An
Arcis a smart pointer that manages multiple atomic references to a value on a heap. In using anArc, a developer can guarantee thread safety for access to a value. To manipulate values references by anArc, you need to first wrap the value in aMutexbefore wrapping it in anArc. - A
Mutexguarantees single-thread access to a value using the.lockmethod. This enables threads to update values at a given reference safely. - Having scanned the Rust book, I couldn't find a high-level API for thread management. I did learn about the
channelconcept which enables threads to pass messages to one another. - The
whereclause is used to improve bounding for traits during generic declarations. The documentation is lacking here and I think it's probably okay to drop this topic for now. - I couldn't find other exciting features for a
closure. But I learned that Rust's compiler will type aclosuredepending on whether it uses variables referenced in another scope.
7 Days of Rust in 45 seconds
Project management
Depend on Rust's package manager cargo:
cargo new <project_name> # Project init
cargo build; cargo compile; cargo run; # Build and run stuff
cargo add <library> # Add dependencies
cargo test # Run your tests
Im- / export your Rust
Declare crates consisting of mods inside of a public function to make code exportable:
pub fn my_crate() {
crate::module_root::to::module()
}
The same :: colon syntax is used to import crates and their submodules. You can import wildcards, a single or multiple module members.
Indeed I do declare
-
letandconstfor variable and constants. -
mutfollowsletif you want to make something mutable.
Control the flow
- Rust supports
if/elsestatements as well asmatchstatements. - Tend towards
matchoverifasmatchis used in several Rust patterns. - You can loop with
loop,forandwhile. Opt forloopif you need to use uninitialised variables or want a returned value frombreak. - Use
.itermethod on collections when iterating to get references to its values.
The important data types
- Use arrays and tuples for fixed size collections of single and mixed types, respectively.
- Use
Vecfor a growable collection. - Favour
Stringover read-only&str -
HashMapsfor single-typed lookups,structsfor logical data groups,enumfor categories - Use
traitsto define interfaces forstructs
DaFunc?
- Declare functions with
fn - Functions are scoped and will shadow variables outside of their scope
- Omit
returnand trailing;to do an implicit return - Anonymous functions are declared using two pipe operators and are called a
closure -
closurescan access variables declared at the same level as them inside their body. Use them for threading!
Pointing out the not obvious
- Static values are stored on the stack, dynamic, unknown or recursive structures are stored on the heap.
- Each value on the heap in Rust can only have one owner, thus reassigning a variable to a new variable will relinquish the latter of its ownership.
- Each value has a scope and it will be dropped once that scope is exited -> do you miss the garbage collector?
- Access values via the
&operator
Catching your errors
- If a function doesn't have a
Resultreturn type, chain its call with.expectto catchpanic. - Otherwise you can use a
matchstatement to handle the error. - Errors are actually referred to as a
panic:D
Stuff I barely understood
- Use the
BoxAPI to allocate a value to the heap - Spawn threads with
thread::spawnand join all threads with.join - Use
Arcto ensure thread-safe resource access
Top comments (0)