Rustlings is a set of small exercises to get acquainted with Rust.
You can take the "recommended path" by running rustlings watch
, which will incrementally move from exercise to exercise and try to compile each of them. The only catch is you need to use the error messages to figure out which file has the error. That looks like this:
⚠️ Compiling of exercises/variables/variables5.rs failed! Please try again. Here's the output:
You also have to remove // I AM NOT DONE
to move on to the next file.
variables 1-5 are the first exercises to run through. This covers syntax around declaring variables, types, making a variable mutable, and the difference between setting a variable to different types. I found variables 5 awkward because there were no instructions for what the intent was. Am I supposed to make this mutable and force it to accept different types? probably not. Am I supposed to parse the string? make the original a number by removing the quotes (or the second by adding quotes)? if so, do I remove the second assignment? In the end I basically just got number 5 running and felt like I skipped it.
fn main() {let number = "3";println!("Number {}", number);number = 3;println!("Number {}", number);}
This one was annoying in the whiteboard-coding style. "Do this thing, but don't use the standard library that everyone uses in regular programs to do it". Feels like if I didn't know where they were trying to lead me already I wouldn't understand the constraints.
// Complete this function to return the bigger number!// Do not use:// - another function call// - additional variables
functions1 is declaring a function.
functions2 is more interesting. We can use num: u32
but I wanted to figure out what the most generic type we could use was. We can use num: impl RangeBounds
but the range still operates on integers (according to Rust error messages), so going further down a generalized rabbit hole is kind of silly and I stopped there.
fn main() {call_me(3);}fn call_me(num: u32) {for i in 0..num {println!("Ring! Call number {}", i + 1);}}
functions5 teaches the importance of semi-colon placement for return values. The following two examples both work.
fn square(num: i32) -> i32 {num * num}
fn square(num: i32) -> i32 {return num * num;}
This does not
fn square(num: i32) -> i32 {num * num;}
Then we come up to test1.rs
which is a test for the functions and variables sections.
Uses ranges, slice syntax, tuple destructuring.
Struct update syntax is like obj/rest in JS, but always fills in unspecified fields rather than "spreading"
let your_order = Order {name: String::from("Hacker in Rust"),count: 1,..order_template};
String::from("some string")"a string".to_string()
Passing strings by reference: &some_string
.
"which of these are Strings and which are &str"
Can't use pub
for a macro in a module.
mod macros {#[macro_export]macro_rules! my_macro {() => {println!("Check out my macro!");};}}