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.
Box
is a way to tell the compiler to put a value on the heap. This makes aBox
a smart pointer. Values should be added to the heap when they are expected to grow or be shared of multiple threads. - An
Arc
is 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 aMutex
before wrapping it in anArc
. - A
Mutex
guarantees single-thread access to a value using the.lock
method. 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
channel
concept which enables threads to pass messages to one another. - The
where
clause 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 aclosure
depending 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
-
let
andconst
for variable and constants. -
mut
followslet
if you want to make something mutable.
Control the flow
- Rust supports
if/else
statements as well asmatch
statements. - Tend towards
match
overif
asmatch
is used in several Rust patterns. - You can loop with
loop
,for
andwhile
. Opt forloop
if you need to use uninitialised variables or want a returned value frombreak
. - Use
.iter
method 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
Vec
for a growable collection. - Favour
String
over read-only&str
-
HashMaps
for single-typed lookups,structs
for logical data groups,enum
for categories - Use
traits
to define interfaces forstructs
DaFunc?
- Declare functions with
fn
- Functions are scoped and will shadow variables outside of their scope
- Omit
return
and trailing;
to do an implicit return - Anonymous functions are declared using two pipe operators and are called a
closure
-
closures
can 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
Result
return type, chain its call with.expect
to catchpanic
. - Otherwise you can use a
match
statement to handle the error. - Errors are actually referred to as a
panic
:D
Stuff I barely understood
- Use the
Box
API to allocate a value to the heap - Spawn threads with
thread::spawn
and join all threads with.join
- Use
Arc
to ensure thread-safe resource access
Top comments (0)