100 exercises to learn Rust
This commit is contained in:
40
book/src/01_intro/00_welcome.md
Normal file
40
book/src/01_intro/00_welcome.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Welcome
|
||||
|
||||
Welcome to **"100 Exercises To Learn Rust"**!
|
||||
|
||||
This course will teach you Rust's core concepts, one exercise at a time.
|
||||
In roughly 100 exercises, you'll go from knowing nothing about Rust to feeling productive on your own.
|
||||
|
||||
## Structure
|
||||
|
||||
Each section in this course introduces a new concept or feature of the Rust language.
|
||||
To verify your understanding, each section is paired with an exercise that you need to solve.
|
||||
|
||||
Each exercise is structured as a Rust package, located in the `exercises` folder.
|
||||
The package contains the exercise itself, instructions on what to do (in `src/lib.rs`), and a test suite to
|
||||
automatically verify your solution.
|
||||
|
||||
### `wr`, the workshop runner
|
||||
|
||||
To navigate through the course, you will be using the `wr` CLI (short for "workshop runner").
|
||||
Install it with:
|
||||
|
||||
```bash
|
||||
cargo install --locked workshop-runner
|
||||
```
|
||||
|
||||
In a new terminal, navigate back to the top-level folder of the repository.
|
||||
Run the `wr` command to start the course:
|
||||
|
||||
```bash
|
||||
wr
|
||||
```
|
||||
|
||||
`wr` will verify the solution to the current exercise.
|
||||
Don't move on to the next section until you've solved the exercise for the current one.
|
||||
|
||||
Enjoy the course!
|
||||
|
||||
## References
|
||||
|
||||
- The exercise for this section is located in `exercises/01_intro/00_welcome`
|
||||
112
book/src/01_intro/01_syntax.md
Normal file
112
book/src/01_intro/01_syntax.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Syntax
|
||||
|
||||
The previous task doesn't even qualify as an exercise, but it already exposed you to quite a bit of Rust **syntax**.
|
||||
Let's review the key bits!
|
||||
|
||||
> We won't cover every single detail of Rust's syntax used in the previous exercise.
|
||||
> Instead, we'll cover _just enough_ to keep going without getting stuck in the details.
|
||||
> One step at a time!
|
||||
|
||||
## Comments
|
||||
|
||||
You can use `//` for single-line comments:
|
||||
|
||||
```rust
|
||||
// This is a single-line comment
|
||||
// Followed by another single-line comment
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
Functions in Rust are defined using the `fn` keyword, followed by the function's name, its input parameters, and its
|
||||
return type.
|
||||
The function's body is enclosed in curly braces `{}`.
|
||||
|
||||
In previous exercise, you saw the `greeting` function:
|
||||
|
||||
```rust
|
||||
// `fn` <function_name> ( <input parameters> ) -> <return_type> { <body> }
|
||||
fn greeting() -> &'static str {
|
||||
// TODO: fix me 👇
|
||||
"I'm ready to __!"
|
||||
}
|
||||
```
|
||||
|
||||
`greeting` has no input parameters and returns a reference to a string slice (`&'static str`).
|
||||
|
||||
### Return type
|
||||
|
||||
The return type can be omitted from the signature if the function doesn't return anything (i.e. if it returns `()`,
|
||||
Rust's unit type).
|
||||
That's what happened with the `test_welcome` function:
|
||||
|
||||
```rust
|
||||
fn test_welcome() {
|
||||
assert_eq!(greeting(), "I'm ready to learn Rust!");
|
||||
}
|
||||
```
|
||||
|
||||
The above is equivalent to:
|
||||
|
||||
```rust
|
||||
// Spelling out the unit return type explicitly
|
||||
// 👇
|
||||
fn test_welcome() -> () {
|
||||
assert_eq!(greeting(), "I'm ready to learn Rust!");
|
||||
}
|
||||
```
|
||||
|
||||
### Returning values
|
||||
|
||||
The last expression in a function is implicitly returned:
|
||||
|
||||
```rust
|
||||
fn greeting() -> &'static str {
|
||||
// This is the last expression in the function
|
||||
// Therefore its value is returned by `greeting`
|
||||
"I'm ready to learn Rust!"
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the `return` keyword to return a value early:
|
||||
|
||||
```rust
|
||||
fn greeting() -> &'static str {
|
||||
// Notice the semicolon at the end of the line!
|
||||
return "I'm ready to learn Rust!";
|
||||
}
|
||||
```
|
||||
|
||||
It is considered idiomatic to omit the `return` keyword when possible.
|
||||
|
||||
### Input parameters
|
||||
|
||||
Input parameters are declared inside the parentheses `()` that follow the function's name.
|
||||
Each parameter is declared with its name, followed by a colon `:`, followed by its type.
|
||||
|
||||
For example, the `greet` function below takes a `name` parameter of type `&str` (a "string slice"):
|
||||
|
||||
```rust
|
||||
// An input parameter
|
||||
// 👇
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}!", name)
|
||||
}
|
||||
```
|
||||
|
||||
If there are multiple input parameters, they must be separated with commas.
|
||||
|
||||
### Type annotations
|
||||
|
||||
Since we've been mentioned "types" a few times, let's state it clearly: Rust is a **statically typed language**.
|
||||
Every single value in Rust has a type and that type must be known to the compiler at compile-time.
|
||||
|
||||
Types are a form of **static analysis**.
|
||||
You can think of a type as a **tag** that the compiler attaches to every value in your program. Depending on the
|
||||
tag, the compiler can enforce different rules—e.g. you can't add a string to a number, but you can add two numbers
|
||||
together.
|
||||
If leveraged correctly, types can prevent whole classes of runtime bugs.
|
||||
|
||||
## References
|
||||
|
||||
- The exercise for this section is located in `exercises/01_intro/01_syntax`
|
||||
Reference in New Issue
Block a user