diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..13566b81b --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..03d9549ea --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..dd01c727f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/tour_of_rust.iml b/.idea/tour_of_rust.iml new file mode 100644 index 000000000..610219404 --- /dev/null +++ b/.idea/tour_of_rust.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..35eb1ddfb --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lessons/en/chapter_1.yaml b/lessons/en/chapter_1.yaml index 389cac320..a8212177e 100644 --- a/lessons/en/chapter_1.yaml +++ b/lessons/en/chapter_1.yaml @@ -12,6 +12,24 @@ Once you get familiar with Rust, you can call yourself a **Rustacean**. That's how people who use, contribute or are interested in Rust call themself. +- title: What is Rust? + content_markdown: > + Rust is a systems programming language that is known for its emphasis on + safety, performance and concurrency. + Rust is designed to provide low-level control over system resources + without sacrificing high-level abstractions. + + What does Rust have different from other programming languages. + - ownership and borrowing + - lifetime + - pattern matching + - concurrency without data races + - traits + - no null or garbage collection + - macros + - cargo + - community and ecosystem + - UTF-8 and Unicode text - title: The Rust Playground code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20println!(%22Welcome%20to%20the%20playground!%20You%20can%20modify%20the%20code%20in%20here.%22)%3B%0A%7D%0A @@ -19,9 +37,37 @@ This tour uses an interactive coding tool from [Rust Playground](https://play.rust-lang.org). - It's a great way to play around with Rust and show others your creativity and challenges! + +- title: What is println!? + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++println%21%28%29%3B%0A++++print%21%28%22There+is+an+empty+line+above+this.+%22%29%3B%0A++++print%21%28%22Isn%27t+it+great%3F%22%29%3B%0A++++println%21%28%29%3B+++++%2F%2F+new+line+at+the+end+of+stdout%0A%7D%0A + content_markdown: > + Unlike other programming languages, where there is a function for + writting text in `stdout` (standard output), Rust uses the `macros` **println!** and **print!**. + We'll talk about `macros` later. + + > `println!` will display using a new line character `\n` at the end of the string + > `print!` will not use the `\n` at the end of the text +- title: How to compile? + content_markdown: > + On Linux / MacOS systems: + ``` + $ rustc main.rs + $ ./main + ``` + + On Windows systems? + ``` + > rustc main.rs + > .\main.exe + ``` + + | Operating System (OS) | terminal commands | + | --------------------- | --------------------------------- | + | Linux / MacOS | $ rustc main.rs
$ ./main | + | Windows | > rustc main.rs
> ./main.exe | - title: Variables code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20%2F%2F%20rust%20infers%20the%20type%20of%20x%0A%20%20%20%20let%20x%20%3D%2013%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20x)%3B%0A%0A%20%20%20%20%2F%2F%20rust%20can%20also%20be%20explicit%20about%20the%20type%0A%20%20%20%20let%20x%3A%20f64%20%3D%203.14159%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20x)%3B%0A%0A%20%20%20%20%2F%2F%20rust%20can%20also%20declare%20and%20initialize%20later%2C%20but%20this%20is%20rarely%20done%0A%20%20%20%20let%20x%3B%0A%20%20%20%20x%20%3D%200%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20x)%3B%0A%7D%0A @@ -65,44 +111,51 @@ out for this keyword. - title: Basic Types code: >- - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20x%20%3D%2012%3B%20%2F%2F%20by%20default%20this%20is%20i32%0A%20%20%20%20let%20a%20%3D%2012u8%3B%0A%20%20%20%20let%20b%20%3D%204.3%3B%20%2F%2F%20by%20default%20this%20is%20f64%0A%20%20%20%20let%20c%20%3D%204.3f32%3B%0A%20%20%20%20let%20bv%20%3D%20true%3B%0A%20%20%20%20let%20t%20%3D%20(13%2C%20false)%3B%0A%20%20%20%20let%20sentence%20%3D%20%22hello%20world!%22%3B%0A%20%20%20%20println!(%0A%20%20%20%20%20%20%20%20%22%7B%7D%20%7B%7D%20%7B%7D%20%7B%7D%20%7B%7D%20%7B%7D%20%7B%7D%20%7B%7D%22%2C%0A%20%20%20%20%20%20%20%20x%2C%20a%2C%20b%2C%20c%2C%20bv%2C%20t.0%2C%20t.1%2C%20sentence%0A%20%20%20%20)%3B%0A%7D%0A + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++let+a+%3D+13u8%3B%0A++++let+b+%3D+7u32%3B%0A++++let+c+%3D+a+as+u32+%2B+b%3B%0A++++println%21%28%22%7B%7D%22%2C+c%29%3B%0A%0A++++let+t+%3D+true%3B%0A++++println%21%28%22%7B%7D%22%2C+t+as+u8%29%3B%0A%0A++++%0A++++let+d%3A+u32+%3D+12%3B%0A++++%2F%2F+let+e%3A+u32+%3D+-12%3B++%2F%2F+unsinged+nubers+include+only+positive+numbers%0A++++let+e%3A+i32+%3D+12%3B%0A++++let+f%3A+i32+%3D+-12%3B%0A++++println%21%28%22%7B%7D+%7B%7D+%7B%7D+%7B%7D%22%2C%0A++++++++++++++++d%2C+-%28d+as+i32%29%2C+e%2C+f%29%3B%0A%7D%0A%0A content_markdown: > + Basic data types: + - bool + - u8 + - u16 + - u32 + - u64 + - u128 + - i8 + - i16 + - i32 + - i64 + - i128 + - usize + - isize + - f32 + - f64 + + | u/i | sign | sign | sign| + | --- | ---------------- | ---------------------------------- | --- | + | `u` | unsigned numbers | positive numbers only | + | + | `i` | signed numbers | both negative and positive numbers | ± | + + Rust has a variety of familiar types: - - - * booleans - `bool` for representing true/false - - * unsigned integers - `u8` `u16` `u32` `u64` `u128` for representing - nonnegative whole numbers - - * signed integers - `i8` `i16` `i32` `i64` `i128` for representing whole numbers - - * pointer sized integers - `usize` `isize` for representing indexes - - and sizes of things in memory - - * floating point - `f32` `f64` - - * tuple - `(value, value, ...)` for passing fixed sequences of values on the - stack - - * arrays - `[value, value, ...]` a collection of similar elements with fixed - length known at compile time - - * slices - a collection of similar elements with length known at runtime - - * `str`(string slice) - text with a length known at runtime - - - Text might be more complex than you are used to in other languages; - - since Rust is a system programming language, it cares about memory - - issues you might not be used to. We will be going into this in detail later. - - - Numeric types can be explicitly specified by appending the type to the end - of the number (e.g. `13u32`, `2u8`). + + - `booleans` - bool for representing true/false + - unsigned integers - `u8` `u16` `u32` `u64` `u128` for representing nonnegative whole numbers + - signed integers - i8 i16 i32 i64 i128 for representing whole numbers + pointer sized integers - usize isize for representing indexes and sizes of things in memory + - floating point - `f32` `f64` + - tuple - `(value, value, ...)` for passing fixed sequences of values on the stack + - arrays - `[value, value, ...]` a collection of similar elements with fixed length known at compile time + - slices - a collection of similar elements with length known at runtime + - `str` (string slice) - text with a length known at runtime + + Text might be more complex than you are used to in other languages; since + Rust is a system programming language, it cares about memory issues you + might not be used to. We will be going into this in detail later. + + Numeric types can be explicitly specified by appending the type to the end + of the number (e.g. `13u32`, `2u8`). + + > cannot apply unary operator '-' on `u8`, `u16`, `u32`, `u64`, `u128` - title: Basic Type Conversion code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20a%20%3D%2013u8%3B%0A%20%20%20%20let%20b%20%3D%207u32%3B%0A%20%20%20%20let%20c%20%3D%20a%20as%20u32%20%2B%20b%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20c)%3B%0A%0A%20%20%20%20let%20t%20%3D%20true%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20t%20as%20u8)%3B%0A%7D%0A @@ -134,9 +187,50 @@ Constant names are always in `SCREAMING_SNAKE_CASE`. +- title: Collections + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=use+std%3A%3Acollections%3A%3AHashMap%3B%0Ause+std%3A%3Acollections%3A%3AHashSet%3B%0A%0Afn+main%28%29+%7B%0A%0A++++%2F%2F+array%0A++++let+array%3A+%5Bi32%3B+3%5D+%3D+%5B1%2C+2%2C+3%5D%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+array%29%3B%0A++++%0A++++%2F%2F+vector%0A++++let+vector%3A+Vec%3Ci32%3E+%3D+vec%21%5B1%2C+2%2C+3%5D%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+vector%29%3B%0A%0A++++%2F%2F+slice+%28from+other+collection%29%0A++++let+slice+%3D+%26array%5B1..3%5D%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+slice%29%3B%0A++++%0A++++%2F%2F+string%0A++++let+string%3A+String+%3D+String%3A%3Afrom%28%22Hello%2C+Rust%21%22%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+string%29%3B%0A++++%0A++++%2F%2F+tuple%0A++++let+tuple%3A+%28i32%2C+f64%2C+u8%29+%3D+%2842%2C+3.14%2C+5%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+tuple%29%3B%0A%0A++++%2F%2F+map%0A++++let+mut+map+%3D+HashMap%3A%3Anew%28%29%3B%0A++++map.insert%28%22one%22%2C+1%29%3B%0A++++map.insert%28%22two%22%2C+2%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+map%29%3B%0A++++%0A++++%2F%2F+set%0A++++let+mut+set+%3D+HashSet%3A%3Anew%28%29%3B%0A++++set.insert%281%29%3B%0A++++set.insert%282%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+set%29%3B%0A%7D%0A + content_markdown: > + Rust provides a variety of collection types that allow you to store and + manipulate data. + + The main collections in Rust: + - Arrays + - Vectors + - Slices + - Strings + - Tuple + - Hash Maps + - Hash Sets + + We will discuss each of them latter on. +- title: Printing with `{:?}` + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A%0A++++let+my_vector+%3D+vec%21%5B1%2C+2%2C+3%5D%3B%0A++++%2F%2F+println%21%28%22%7B%7D%22%2C+my_vector%29%3B+++%2F%2F+will+generate+an+error%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+my_vector%29%3B%0A++++println%21%28%22%7B%3A%23%3F%7D%22%2C+my_vector%29%3B+++%2F%2F+debug+mode%0A++++%0A++++let+x%3A+i32+%3D+-12%3B%0A++++println%21%28%22%7B%7D%22%2C+x%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+x%29%3B%0A++++println%21%28%22%7B%3A%23%3F%7D%22%2C+x%29%3B%09%0A%7D%0A + content_markdown: > + Notice that when displaying a collection, `println!("{}", collection);` + doesn't work. + + In Rust, the `:?` is a format specifier used with the `Debug` trait when + printing values / collections of values. + When you use `println!("{:?}", x);`, the Rust compiler formats the variable + accordingly. + + This is particularly useful for `collections` like vectors, arrays, structs + and enums. + + `{:#?}` will print them in a way that is designed to be informative during + debugging. + + + | function | basic type | collection | + | --------------------- | ---------- | ---------- | + | println!("{}", x); | ✅ | ❌ | + | println!("{:?}", x); | ✅ | ✅ | + | println!("{:#?}", x); | ✅ | ✅ | - title: Arrays code: >- - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20nums%3A%20%5Bi32%3B%203%5D%20%3D%20%5B1%2C%202%2C%203%5D%3B%0A%20%20%20%20println!(%22%7B%3A%3F%7D%22%2C%20nums)%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20nums%5B1%5D)%3B%0A%7D%0A + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++let+nums%3A+%5Bi32%3B+5%5D+%3D+%5B1%2C+2%2C+3%2C+4%2C+5%5D%3B%0A%0A++++println%21%28%22%7B%7D%22%2C+nums%5B1%5D%29%3B%0A%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+nums%29%3B+++++%2F%2F+%3A%3F+for+displaying+collections%0A++++println%21%28%22%7B%3A%23%3F%7D%22%2C+nums%29%3B++++%2F%2F+%3A%23%3F+displaying+a+collection+in+debug+mode%0A++++%0A++++for+el+in+nums+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+el%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A++++%0A++++for+i+in+0..%3D%28nums.len%28%29+-+1%29+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+nums%5Bi%5D%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A++++%0A++++for+i+in+0..nums.len%28%29+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+nums%5Bi%5D%29%3B%0A++++%7D%0A++++println%21%28%22%22%29%3B%0A%7D%0A content_markdown: > An *array* is a **fixed length collection** of data elements all of the same type. @@ -152,9 +246,42 @@ Collections with a dynamic length, often called dynamic or variable arrays, are introduced in a later chapter about **Vectors**. +- title: Vectors + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++%2F%2F+vec%21%5B%5D+is+a+macro%0A++++let+v1+%3D+vec%21%5B1%2C+2%2C+3%2C+4%2C+5%5D%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+v1%29%3B%0A++++%0A++++let+mut+v2+%3D+Vec%3A%3Anew%28%29%3B%0A++++v2.push%281%29%3B%0A++++v2.push%282%29%3B%0A++++v2.push%283%29%3B%0A++++%0A++++%2F%2F+Using+a+for+loop%0A++++for+el+in+%26v1+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+el%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A++++%0A++++%2F%2F+Using+iter%28%29+method%0A++++for+el+in+v1.iter%28%29+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+el%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A++++%0A++++for+i+in+0..v1.len%28%29+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+v1%5Bi%5D%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A++++%0A++++%0A++++%2F%2F+we%27ll+talk+about+Some+and+Result+later%0A++++if+let+Some%28element%29+%3D+v1.get%281%29+%7B%0A++++++++println%21%28%22Second+element%3A+%7B%7D%22%2C+element%29%3B%0A++++%7D+else+%7B%0A++++++++println%21%28%22Index+out+of+bounds.%22%29%3B%0A++++%7D%0A++++%0A%7D%0A + content_markdown: > + Vectors are on of the most flexible and commonly used collection types in Rust. + + They represent a dynamic, growable array, and they are part of the standard + + Rust library (`std::vec::Vec`). No need to `use` it. :) +- title: Strings + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++let+str1+%3D+%22Hello%2C+world%22%3B+%2F%2F+%26str+Type%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+str1%29%3B%0A++++%0A++++let+mut+s1%3A+String+%3D+String%3A%3Afrom%28%22%22%29%3B%0A++++s1.push_str%28%22Hello%22%29%3B%0A++++s1.push_str%28%22%2C+world%21%22%29%3B%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+s1%29%3B%0A++++%0A++++let+s2%3A+String+%3D+String%3A%3Afrom%28%22Rust%22%29%3B%0A++++let+s3%3A+String+%3D+s1+%2B+%26s2%3B++%2F%2F+s1+will+be+moved+to+s3%0A++++println%21%28%22%7B%3A%3F%7D%22%2C+s3%29%3B%0A++++%2F%2F+println%21%28%22%7B%3A%3F%7D%22%2C+s1%29%3B++++%2F%2F+doesn%27t+work+%3A+s1+is+borrowed+by+s3%0A++++%0A++++let+s4%3A+String+%3D+s3.clone%28%29%3B%0A++++for+ch+in+s4.chars%28%29+%7B%0A++++++++print%21%28%22%7B%7D%22%2C+ch%29%3B%0A++++%7D%0A++++%0A%7D%0A + content_markdown: > + In Rust strings are UTF-8 encoded sequence of Unicode characters. + + The String type, which is part of the standard library + (`std::string::String`), is the most commonly used string type in Rust. + + Rust also has a primitive string type, `&str`, which represents a string slice. + + We'll later discuss in detail about Strings. +- title: Tuple + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++%2F%2F+Create+a+tuple%0A++++let+my_tuple+%3D+%2811%2C+%22Hello%2C+Rust%21%22%2C+3.14%29%3B%0A%0A++++%2F%2F+Access+elements+using+indexing%0A++++let+first_element+%3D+my_tuple.0%3B%0A++++let+second_element+%3D+my_tuple.1%3B%0A++++let+third_element+%3D+my_tuple.2%3B%0A%0A++++%2F%2F+Print+the+elements%0A++++println%21%28%22First%3A+%7B%7D%22%2C+first_element%29%3B%0A++++println%21%28%22Second%3A+%7B%7D%22%2C+second_element%29%3B%0A++++println%21%28%22Third%3A+%7B%7D%22%2C+third_element%29%3B%0A%7D%0A + content_markdown: > + `Tuple` represents an **immutable** collections of elements, that can have + different data types. + + Since it's **immutable**, it cannot be modified after its creation. + + The elements of a tuple can be accessed by index (indexing starts from 0), + using the `.` operator. + - title: Functions code: >- - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20add(x%3A%20i32%2C%20y%3A%20i32)%20-%3E%20i32%20%7B%0A%20%20%20%20return%20x%20%2B%20y%3B%0A%7D%0A%0Afn%20subtract(x%3A%20i32%2C%20y%3A%20i32)%20-%3E%20i32%20%7B%0A%20%20%20%20x%20-%20y%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%2242%20%2B%2013%20%3D%20%7B%7D%22%2C%20add(42%2C%2013))%3B%0A%20%20%20%20println!(%2242%20-%2013%20%3D%20%7B%7D%22%2C%20subtract(42%2C%2013))%3B%0A%7D%0A + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+add%28x%3A+i32%2C+y%3A+i32%29+-%3E+i32+%7B%0A++++return+x+%2B+y%3B%0A%7D%0A%0Afn+subtract%28x%3A+i32%2C+y%3A+i32%29+-%3E+i32+%7B%0A++++x+-+y%0A%7D%0A%0Afn+last_digit%28mut+x%3A+i32%29+-%3E+u8+%7B%0A++++%0A++++if+x+%3C+0+%7B%0A++++++++while+x+%3C+-9+%7B%0A++++++++++++x+%3D+x+%2F+10%3B%0A++++++++%7D%0A++++++++return+%28-x%29+as+u8%3B%0A++++%0A++++%7D+else+%7B%0A++++++++while+x+%3E+9+%7B%0A++++++++++++x+%3D+x+%2F+10%3B%0A++++++++%7D%0A++++++++return+x+as+u8%3B%0A++++%7D%0A%7D%0A%0Afn+main%28%29+%7B%0A++++println%21%28%2242+%2B+13+%3D+%7B%7D%22%2C+add%2842%2C+13%29%29%3B%0A++++println%21%28%2242+-+13+%3D+%7B%7D%22%2C+subtract%2842%2C+13%29%29%3B%0A++++%0A++++let+mut+nr+%3D+612129%3B%0A++++println%21%28%22last+digit+of+%7B%7D+%3D+%7B%7D%22%2C+nr%2C+last_digit%28nr%29%29%3B%0A%0A++++nr+%3D+-31324%3B%0A++++println%21%28%22last+digit+of+%7B%7D+%3D+%7B%7D%22%2C+nr%2C+last_digit%28nr%29%29%3B%0A%7D%0A content_markdown: > A function has zero or more parameters. @@ -202,6 +329,28 @@ whats happening. code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20make_nothing()%20-%3E%20()%20%7B%0A%20%20%20%20return%20()%3B%0A%7D%0A%0A%2F%2F%20the%20return%20type%20is%20implied%20as%20()%0Afn%20make_nothing2()%20%7B%0A%20%20%20%20%2F%2F%20this%20function%20will%20return%20()%20if%20nothing%20is%20specified%20to%20return%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20let%20a%20%3D%20make_nothing()%3B%0A%20%20%20%20let%20b%20%3D%20make_nothing2()%3B%0A%0A%20%20%20%20%2F%2F%20Printing%20a%20debug%20string%20for%20a%20and%20b%0A%20%20%20%20%2F%2F%20Because%20it's%20hard%20to%20print%20nothingness%0A%20%20%20%20println!(%22The%20value%20of%20a%3A%20%7B%3A%3F%7D%22%2C%20a)%3B%0A%20%20%20%20println!(%22The%20value%20of%20b%3A%20%7B%3A%3F%7D%22%2C%20b)%3B%0A%7D%0A +- title: Macros + content_markdown: > + A `macro` is an abstraction from another code, that allows developers to + define reusable patterns and reduce duplicate code. + + In Rust, there are two types of `macros`: + - declarative + - procedural +- title: Declarative macros + content_markdown: > + Declarative macros, such as **print!**, **format!** or **todo!** + are invoked using the syntax `macro_name!(....)`. + + The `!` indicates that it's a macro invocation + rather than a regular function call. +- title: Procedural macros + content_markdown: > + Procedural macros operate on the abstract syntax tree (AST) of Rust code and + generate or modify code accordingly. They are more powerful and flexible + than declarative macros but are also more complex. + + Examples: `#[derive(Debug)]`, `#[test]`, `#[derive(Serialize)]` - title: Chapter 1 - Conclusion content_markdown: > Nice job so far! The basics of Rust aren't so bad, right? We're diff --git a/lessons/en/chapter_10.yaml b/lessons/en/chapter_10.yaml index aa170fcf4..d13c142ed 100644 --- a/lessons/en/chapter_10.yaml +++ b/lessons/en/chapter_10.yaml @@ -1,10 +1,150 @@ -- title: Chapter 10 - The End +- title: Chapter 10 - I/O content_markdown: > - It's been a joy to have you on the Tour of Rust. Ferris and the Tour of Rust - team sincerely hope you enjoy the journey ahead! If you + In computing, `I/O` is an abbreviation for `Input/Output` operation. + + The `input` is that the computer and tha algorithm receive and + the `output` represents the result generated based on the `input`. + + Thing about `I/O` as a stream of information + + A compute system without output is nearly useless. + + It will always run the same code on the same data and, thus, produce the same result. - have felt comfortable this far, we strongly recommend diving deeper with - these resources: +- title: Do it locally + content_markdown: > + In this chapter, the Playground will be just a code support for you :(. + + Since most of the `I/O` programs are designed to compile on a local machine + (yours :) ), consider setting up a Rust environment on your personal computer and + familiarise yourself with the terminal. + + Also, consider using a `IDE`, such as `VS Code` or `RustRover` + and familiarise yourself with the [terminal](https://www.youtube.com/watch?v=lZ7Kix9bjPI). + +- title: Standard Input (stdin) + content_markdown: > + `Standard Input` refers to the data provided by the user in order for the algorithm + to make something with it. + + + Thus, the `input` represents what a program is being given. + Mostly, in terms of `input`, you'll work with `String` and `files`. + + + The Rust library `std::io` has the necessary components to interact with `I/O` + channels, such as the keyboard or any other input source. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A + +- title: Standard Output (stdout) + content_markdown: > + Remember the first lesson? Can you notice something relevant to `I/O`? + + Of course that `println!` is does an output operation, + in fact it directs (outputs) text to `stdout` (stdout) + and it will be displayed on the screen. + + If you don't want to print a new line character `\n` for you, use `print!` + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A + +- title: Standard Error (stdout) + content_markdown: > + In order to separate error reporting from common printing, you can use `eprint!` and + `eprintln!` macros that will display text in the standard error (`stderr`) channel, + instead of `stdout`. Use this macro with an informative message. + + In UNIX-like systems, such as macOS or LINUX, you can separate the two types of + output by using redirections: + - `./main > output.txt` + - `./main >> output.txt` + - `./main 2> output.txt` + - `./main 2>> output.txt` + + + > The commands with `2` with copy only the errors generated by the program, and the ones without `2` will discards all error. + + > THe command with `>>` will add text at the end of the file, while the operator `>` will override the file. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A + +- title: File Descriptors + content_markdown: > + Now that we know what are the basic `I/O` operations, we dive even deeper. + + You've already seen before: `stdin` (standard input), `stdout` (standard output) and `stderr` (stand error). + For each of them it is associated a positive integer number, a unique identifier + for an `I/O` channel (example: file), known as a `file descriptor (fd)`. - * [The Official Rust Programming - Book](https://doc.rust-lang.org/stable/book/) + Therefore: + - `stdin`: 0 + - `stdout`: 1 + - `stderr`: 2 + - files + + [![file descriptors](https://cs-pub-ro.github.io/operating-systems/assets/images/file-descriptors-d19424f0a417ecd1c032f98a1969ad75.svg) + + + Working with files plays an important role in the `I/O` operations. + + You've already learned to open a text file and read its content. + + But how about writing data in it, as an `I/O` channel. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Afs%3A%3A%7Bself%2C+File%7D%3B++++++%2F%2F+file+system%0Ause+std%3A%3Aio%3A%3A%7Bself%2C+Write%7D%3B+++++%2F%2F+input+output%0A%0Afn+main%28%29+-%3E+io%3A%3AResult%3C%28%29%3E+%7B%0A++++let+file_name+%3D+%22output.txt%22%3B%0A%0A++++%2F%2F+creates+the+file+if+it+doesn%27t+already+exists%0A++++let+mut+file+%3D+File%3A%3Acreate%28file_name%29%3F%3B%0A%0A++++let+text_to_write+%3D+%22Hello%2C+World%21%5Cn%5C%0A++++++++++++++++++++++++++++This+is+a+line+of+text.%5Cn%22%3B%0A++++file.write_all%28text_to_write.as_bytes%28%29%29%3F%3B%0A%0A++++let+absolute_path+%3D+fs%3A%3Acanonicalize%28file_name%29%3F%3B%0A++++println%21%28%22Text+has+been+written+to%3A+%7B%3A%3F%7D%22%2C+absolute_path%29%3B%0A%0A++++return+Ok%28%28%29%29%3B%0A%7D%0A + +- title: System Arguments + content_markdown: > + A Rust program is able to receive `input` from the in-line arguments. + + In order to do so, open a [terminal](https://www.youtube.com/watch?v=lZ7Kix9bjPI), compile it and pass the arguments to the executable in the command promt. + + These arguments might be relevant files, flags and so on. + The developer must document their purpose. + + If you are using LINUX or macOS, bear in mind these commands: + ```bash + $ touch main.rs + $ rustc main.rs + $ ./main.rs 2 3 4 5 + ``` + + Otherwise, for Windows environment, on a PowerShell and paste them + ```PowerShell + > echo. > main.rs + > rustc main.rs + > .\main.exe 2 3 4 5 + ``` + + + > Notice that the first argument is the executable itself + + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aenv%3B+++++++%2F%2F+env+stands+for+environment%0A%0Afn+main%28%29+%7B%0A++++let+args%3A+Vec%3CString%3E+%3D+env%3A%3Aargs%28%29.collect%28%29%3B%0A++++println%21%28%22number+of+arguments+%3D+%7B%7D%22%2C+args.len%28%29%29%3B%0A++++println%21%28%22the+inline+arguments+are+%3A+%7B%3A%3F%7D%22%2C+args%29%3B%0A%7D%0A + +- title: Environment Variables + content_markdown: > + You've seen that the Rust standard library grants access to the system. + + Using the `std::env` module, you can do in Rust some task that might require + a UNIX terminal, such as: + - command line arguments + - printing the current working directory + - current executable path + - working with environmental variables + - working with files and directories + + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aenv%3B+++%2F%2F+for+interacting+with+the+system%27s+environment%0A%0Afn+main%28%29+%7B%0A%0A++++if+let+Ok%28current_dir%29+%3D+env%3A%3Acurrent_dir%28%29+%7B%0A++++++++if+let+Some%28pwd%29+%3D+current_dir.to_str%28%29+%7B%0A++++++++++++println%21%28%22The+current+working+directory+%3D+%7B%7D%22%2C+pwd%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2F+%24+echo+%24PWD++++++%23+environment+variable%0A++++%2F%2F+if+you+don%27t+want+to+see+Seme%28...%29%2C+you+have+to+pattern+match+on+Ok%28%29%0A++++println%21%28%22The+current+working+directory+%3D+%7B%3A%3F%7D%22%2C+env%3A%3Avar%28%22PWD%22%29.ok%28%29%29%3B%0A%0A++++%2F%2F+%24+echo+%24PWD++++++%23+environment+variable%0A++++if+let+Ok%28pwd%29+%3D+env%3A%3Avar%28%22PWD%22%29+%7B%0A++++++++println%21%28%22The+current+working+directory+%3D+%7B%7D%22%2C+pwd%29%3B%0A++++%7D%0A%0A++++%2F%2F+%24+echo+%24USER+++++%23+environment+variable%0A++++if+let+Ok%28user%29+%3D+env%3A%3Avar%28%22USER%22%29+%7B%0A++++++++println%21%28%22The+current+user+is%3A+%7B%7D%22%2C+user%29%3B%0A++++%7D%0A%0A%0A++++%2F%2F+%24+echo+%24IDK++++++%23+I+suppose+you+didn%27t+set+this+variable+%3A%29%0A++++if+let+Err%28err%29+%3D+env%3A%3Avar%28%22IDK%22%29+%7B%0A++++++++eprintln%21%28%22IDK+%3A+%7B%7D%22%2C+err%29%3B%0A++++++++env%3A%3Aset_var%28%22IDK%22%2C+%22%3D+I+don%27t+know%22%29%3B%0A++++++++println%21%28%22IDK+%3D+%7B%3A%3F%7D%22%2C+env%3A%3Avar%28%22IDK%22%29.ok%28%29%29%3B%0A++++++++env%3A%3Aremove_var%28%22IDK%22%29%3B%0A++++%7D%0A%7D%0A +- title: Chapter 11 - Conclusion + content_markdown: > + Now that you know the basic of Input/Output operations, you used just two + Rust libraries along the way, and they are standard, btw: `std::env` and `std::fs`. + + Now, you can build your own file managing system, Web App or even API. + + Checkout these resources: + - [Environment Variables](https://youtu.be/npsMN-tZNVs) + - [Rust API](https://youtu.be/_ccDqRTx-JU) + diff --git a/lessons/en/chapter_11.yaml b/lessons/en/chapter_11.yaml new file mode 100644 index 000000000..3b72c2374 --- /dev/null +++ b/lessons/en/chapter_11.yaml @@ -0,0 +1,10 @@ +- title: Chapter 11 - The End + content_markdown: > + It's been a joy to have you on the Tour of Rust. Ferris and the Tour of Rust + team sincerely hope you enjoy the journey ahead! If you + + have felt comfortable this far, we strongly recommend diving deeper with + these resources: + + * [The Official Rust Programming + Book](https://doc.rust-lang.org/stable/book/) diff --git a/lessons/en/chapter_2.yaml b/lessons/en/chapter_2.yaml index af4974bef..b5e73cbf7 100644 --- a/lessons/en/chapter_2.yaml +++ b/lessons/en/chapter_2.yaml @@ -67,33 +67,49 @@ and including an end number. code: >- - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20for%20x%20in%200..5%20%7B%0A%20%20%20%20%20%20%20%20println!(%22%7B%7D%22%2C%20x)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20for%20x%20in%200..%3D5%20%7B%0A%20%20%20%20%20%20%20%20println!(%22%7B%7D%22%2C%20x)%3B%0A%20%20%20%20%7D%0A%7D%0A + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A%0A++++for+x+in+0..5+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+x%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A%0A++++for+x+in+0..%3D5+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+x%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A%0A++++let+nums+%3A+%5Bi32%3B+5%5D+%3D+%5B10%2C+-1%2C+9%2C+-80%2C+1%5D%3B%0A++++%0A++++print%21%28%22%7B%7D+%3A+%22%2C+stringify%21%28nums%29%29%3B%0A++++for+el+in+nums+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+el%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A%0A++++print%21%28%22%7B%7D+%3A+%22%2C+stringify%21%28nums%29%29%3B%0A++++for+idx+in+0+..+nums.len%28%29+%7B%0A++++++++print%21%28%22%7B%7D+%22%2C+nums%5Bidx%5D%29%3B%0A++++%7D%0A++++println%21%28%29%3B%0A%7D%0A - title: match content_markdown: > - Miss your switch statement? Rust has an incredibly useful keyword + Miss your switch statement? + + Rust has an incredibly useful keyword for + matching all possible conditions of a value + and executing a code path if the match is true. + + Let's see how this works for numbers. We will have more to + say in future chapters on pattern matching more complex data. I promise you + it will be worth the wait. + + + `match` is exhaustive so all cases must be handled. + + If the branches do not cover all the possible cases, + we'll use the underscore `_`, that will take place for the rest of them, + + Matching combined with destructuring is by far one of the most common patterns you will see in all of Rust. - for matching all possible conditions of a value and executing a code path if - the - - match is true. Let's see how this works for numbers. We will have more to - say - - in future chapters on pattern matching more complex data. I promise you it - will - be worth the wait. - - - `match` is exhaustive so all cases + Matching combined with destructuring is by far one of the + most common patterns you will see in all of Rust. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn+main%28%29+%7B%0A++++let+x+%3D+42%3B%0A%0A++++match+x+%25+2+%3D%3D+0+%7B%0A++++++++true+%3D%3E+println%21%28%22%7B%7D+is+an+even+number%22%2C+x%29%2C%0A++++++++false+%3D%3E+println%21%28%22%7B%7D+is+an+odd+number%22%2C+x%29%2C%0A++++%7D%0A%0A++++match+x+%7B%0A++++++++0+%3D%3E+%7B%0A++++++++++++println%21%28%22found+zero%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+match+against+multiple+values%0A++++++++1+%7C+2+%3D%3E+%7B%0A++++++++++++println%21%28%22found+1+or+2%21%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+match+against+ranges%0A++++++++3..%3D9+%3D%3E+%7B%0A++++++++++++println%21%28%22found+a+number+3+to+9+inclusively%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+bind+the+matched+number+to+a+variable%0A++++++++matched_num+%40+10..%3D100+%3D%3E+%7B%0A++++++++++++println%21%28%22found+%7B%7D+number+between+10+to+100%21%22%2C+matched_num%29%3B%0A++++++++%7D%0A++++++++%2F%2F+do+nothing+if+x+equals+101%0A++++++++101+%3D%3E+%28%29%2C%0A++++++++%2F%2F+this+is+the+default+match+that+must+exist+if+not+all+cases+are+handled%0A++++++++_+%3D%3E+%7B%0A++++++++++++println%21%28%22found+something+else%21%22%29%3B%0A++++++++%7D%0A++++%7D%0A%7D%0A +- title: matching multiple parameters + content_markdown: > + The `match` statements expects a tuple. - must be handled. + Notice that, unlike the `if` statement, + the code will compile just fine if you try + to place the evaluation elements in parenthesis `()`. + But why?...🤔 - Matching combined with destructuring is by far one of the + Because the element is seen as a `tuple` + (a collection of elements that are able to have different types). - most common patterns you will see in all of Rust. + `tuples` are really powerful to use if you want + to match multiple elements together. code: >- - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20x%20%3D%2042%3B%0A%0A%20%20%20%20match%20x%20%7B%0A%20%20%20%20%20%20%20%200%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20println!(%22found%20zero%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20we%20can%20match%20against%20multiple%20values%0A%20%20%20%20%20%20%20%201%20%7C%202%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20println!(%22found%201%20or%202!%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20we%20can%20match%20against%20ranges%0A%20%20%20%20%20%20%20%203..%3D9%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20println!(%22found%20a%20number%203%20to%209%20inclusively%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20we%20can%20bind%20the%20matched%20number%20to%20a%20variable%0A%20%20%20%20%20%20%20%20matched_num%20%40%2010..%3D100%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20println!(%22found%20%7B%7D%20number%20between%2010%20to%20100!%22%2C%20matched_num)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%2F%2F%20this%20is%20the%20default%20match%20that%20must%20exist%20if%20not%20all%20cases%20are%20handled%0A%20%20%20%20%20%20%20%20_%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20println!(%22found%20something%20else!%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D%0A + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn+main%28%29+%7B%0A++++let+x+%3D+42%3B%0A++++let+y+%3D+-101%3B%0A+%0A++++%2F%2F+the+program+compiles%0A++++%2F%2F+but+the+parantheses+are+unnecessary+for+just+an+element%0A++++match+%28x+%25+2+%3D%3D+0%29+%7B%0A++++++++%28true%29+%3D%3E+println%21%28%22%7B%7D+is+an+even+number%22%2C+x%29%2C%0A++++++++false+%3D%3E+println%21%28%22%7B%7D+is+an+odd+number%22%2C+x%29%2C%0A++++%7D%0A%0A+%0A++++match+%28x+%3E%3D+0%2C+y+%3E%3D+0%29+%7B%0A++++++++%28true%2C+true%29+%3D%3E+println%21%28%22Both+numbers+%7B%7D+%7B%7D+are+positive%22%2C+x%2C+y%29%2C%0A++++++++%28true%2C+false%29+%3D%3E+println%21%28%22Only+%7B%7D+is+a+positive+number%22%2C+x%29%2C%0A++++++++%28false%2C+true%29+%3D%3E+println%21%28%22Only+%7B%7D+is+a+negative+number%22%2C+y%29%2C%0A++++++++%28false%2C+false%29+%3D%3E+println%21%28%22Both+numbers+%7B%7D+%7B%7D+are+negative%22%2C+x+%2Cy%29%2C%0A++++%7D%0A%7D%0A - title: Returning Values From loop content_markdown: | `loop` can break to return a value. diff --git a/lessons/en/chapter_4.yaml b/lessons/en/chapter_4.yaml index f55c2bf47..e0c6479d1 100644 --- a/lessons/en/chapter_4.yaml +++ b/lessons/en/chapter_4.yaml @@ -181,6 +181,32 @@ Be a good rustacean and properly use `match` when you can! code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20do_something_that_might_fail(i%3A%20i32)%20-%3E%20Result%3Cf32%2C%20String%3E%20%7B%0A%20%20%20%20if%20i%20%3D%3D%2042%20%7B%0A%20%20%20%20%20%20%20%20Ok(13.0)%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20Err(String%3A%3Afrom(%22this%20is%20not%20the%20right%20number%22))%0A%20%20%20%20%7D%0A%7D%0A%0Afn%20main()%20-%3E%20Result%3C()%2C%20String%3E%20%7B%0A%20%20%20%20%2F%2F%20concise%20but%20assumptive%20and%20gets%20ugly%20fast%0A%20%20%20%20let%20v%20%3D%20do_something_that_might_fail(42).unwrap()%3B%0A%20%20%20%20println!(%22found%20%7B%7D%22%2C%20v)%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20this%20will%20panic!%0A%20%20%20%20let%20v%20%3D%20do_something_that_might_fail(1).unwrap()%3B%0A%20%20%20%20println!(%22found%20%7B%7D%22%2C%20v)%3B%0A%20%20%20%20%0A%20%20%20%20Ok(())%0A%7D%0A +- title: if let + content_markdown: > + A much easier way to handle error propagation in Rust + is to use the `if let` block. It basically handles just + the only `match` branch that we are interested to get. + + For instance, if we want to get the **error**, + `if let Err(..) = ..` will be used. + + Otherwise, `if let Ok(..) = ..` will be chosen + to handle the **success** case. + + `if let` can be used only for `Result` and `Option` data tyes. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn+main%28%29+%7B%0A++++let+x+%3D+42%3B%0A%0A++++match+x+%25+2+%3D%3D+0+%7B%0A++++++++true+%3D%3E+println%21%28%22%7B%7D+is+an+even+number%22%2C+x%29%2C%0A++++++++false+%3D%3E+println%21%28%22%7B%7D+is+an+odd+number%22%2C+x%29%2C%0A++++%7D%0A%0A++++match+x+%7B%0A++++++++0+%3D%3E+%7B%0A++++++++++++println%21%28%22found+zero%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+match+against+multiple+values%0A++++++++1+%7C+2+%3D%3E+%7B%0A++++++++++++println%21%28%22found+1+or+2%21%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+match+against+ranges%0A++++++++3..%3D9+%3D%3E+%7B%0A++++++++++++println%21%28%22found+a+number+3+to+9+inclusively%22%29%3B%0A++++++++%7D%0A++++++++%2F%2F+we+can+bind+the+matched+number+to+a+variable%0A++++++++matched_num+%40+10..%3D100+%3D%3E+%7B%0A++++++++++++println%21%28%22found+%7B%7D+number+between+10+to+100%21%22%2C+matched_num%29%3B%0A++++++++%7D%0A++++++++%2F%2F+do+nothing+if+x+equals+101%0A++++++++101+%3D%3E+%28%29%2C%0A++++++++%2F%2F+this+is+the+default+match+that+must+exist+if+not+all+cases+are+handled%0A++++++++_+%3D%3E+%7B%0A++++++++++++println%21%28%22found+something+else%21%22%29%3B%0A++++++++%7D%0A++++%7D%0A%7D%0A +- title: About panic! + content_markdown: > + In Rust, `panic!` is a macro used to stop the execution of the program + without a recoverable error. When a panic occurs, the program immediately + stops, unwinding the stack and cleaning up resources along the way. + + Moreover, the code instructions written after `panic!` will no longer be executed. + + Usually, `panics` can by avoided by pattern matching the error with `Result`. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++println%21%28%22Reachable.%22%29%3B%0A%0A++++%2F%2F+Generates+a+panic%0A++++panic%21%28%22This+is+a+panic%21%22%29%3B%0A%0A++++%2F%2F+This+line+be+executed%0A++++println%21%28%22Unreachable%22%29%3B%0A%7D%0A - title: Vectors content_markdown: > Some of the most useful generic types are collection types. A vector is a diff --git a/lessons/en/chapter_7.yaml b/lessons/en/chapter_7.yaml index 430bc5c2a..7862603d8 100644 --- a/lessons/en/chapter_7.yaml +++ b/lessons/en/chapter_7.yaml @@ -38,6 +38,39 @@ That said, Rust implements many programming language features, so that you might not mind this lacking. +- title: self and Self + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=struct+Coordinates+%7B%0A++++x%3A+i32%2C%0A++++y%3A+i32%2C%0A%7D%0A%0Aimpl+Coordinates+%7B%0A++++%2F%2F+the+return+value%2C+Self%2C+has+the+data+type+as+the+implemented+struct+%0A++++%2F%2F+this+method+is+static%0A++++fn+new%28xval%3A+i32%2C+yval%3A+i32%29+-%3E+Self+%7B%0A++++++++return+Coordinates+%7B%0A++++++++++++x%3A+xval%2C%0A++++++++++++y%3A+yval%2C%0A++++++++%7D%0A++++%7D%0A++++%0A++++fn+setx%28%26mut+self%2C+xval%3A+i32%29+%7B%0A++++++++self.x+%3D+xval%3B%0A++++%7D%0A++++%0A++++fn+sety%28%26mut+self%2C+yval%3A+i32%29+%7B%0A++++++++self.y+%3D+yval%3B%0A++++%7D%0A++++%0A++++fn+disp%28%26self%29+%7B%0A++++++++println%21%28%22Point+located+at+%3A+%7B%7D+on+OX++%7B%7D+on+OY%22%2C%0A++++++++++++++++self.x%2C+self.y%29%3B%0A++++%7D%0A++++%0A%7D%0A%0Afn+main%28%29+%7B%0A++++let+mut+p+%3D+Coordinates%3A%3Anew%28-1i32%2C+1i32%29%3B%0A++++p.disp%28%29%3B%0A++++p.setx%2810++as+i32%29%3B%0A++++p.sety%28-10+as+i32%29%3B%0A++++p.disp%28%29%3B%0A%7D%0A + content_markdown: > + In Rust, `self` and `Self` are fundamental concepts in ownership and + borrowing system. Both of them are used in `impl` and `trait` blocks. + + `self`: + - refers to an **instance of struct** + - reference to itself + - is the first parameter of the method + - method conataining the `self` parameter are called using the name of the instance, the operator `.` and the name of the method + + + `Self`: + - refers to **return type** of the method + - has the same data type as the `struct` that is implemented in a `impl` block + - can be used for static method using the operator `::` (static method do not depend on a instance of a struct and a static method does not contain `self` as parameter) +- title: Defining a macro + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=struct+Coordinates+%7B%0A++++x%3A+i32%2C%0A++++y%3A+i32%2C%0A%7D%0A%0Aimpl+Coordinates+%7B%0A++++%2F%2F+original+copy+constructor%2C+a+static+method%0A++++fn+new%28xval%3A+i32%2C+yval%3A+i32%29+-%3E+Self+%7B%0A++++++++Coordinates+%7B+x%3A+xval%2C+y%3A+yval+%7D%0A++++%7D%0A%7D%0A%0Aimpl+Coordinates+%7B%0A++++fn+disp%28%26self%29+%7B%0A++++++++println%21%28%22Point+located+at%3A+%7B%7D+on+OX%2C+%7B%7D+on+OY%22%2C+self.x%2C+self.y%29%3B%0A++++%7D%0A%7D%0A%0A%2F%2F+the+coord%21+macro%0Amacro_rules%21+coord+%7B%0A++++%28%24x%3Aexpr%2C+%24y%3Aexpr%29+%3D%3E+%7B%0A++++++++Coordinates%3A%3Anew%28%24x%2C+%24y%29%0A++++%7D%3B%0A%7D%0A%0Afn+main%28%29+%7B%0A++++%2F%2F+Use+the+coord%21+macro+to+create+a+new+Coordinates+instance%0A++++let+p1%3A+Coordinates+%3D+coord%21%281%2C+2%29%3B%0A%0A++++%2F%2F+Alternatively%2C+you+can+use+the+coord%21+macro+with+square+brackets%0A++++let+p2+%3D+coord%21%5B2%2C+2%5D%3B%0A++++%0A++++let+p3+%3D+Coordinates+%7B%0A++++++++x%3A+10i32%2C%0A++++++++y%3A+11+as+i32%2C%0A++++%7D%3B%0A++++%0A++++let+p4+%3D+Coordinates%3A%3Anew%28-10%2C+11%29%3B%0A%0A++++p1.disp%28%29%3B%0A++++p2.disp%28%29%3B%0A++++p3.disp%28%29%3B%0A++++p4.disp%28%29%3B%0A%7D%0A + content_markdown: > + We talked before that we can use `macros` to simplify abstractions of our code. + + Let us define a `macro` that has the functionality of a copy constructor + for a struct. + + Notice that we group the macro's parameters using either `()` or `[]`. + + The choice between using `()` and `[]` for `macro` invocations in Rust + often depends on the expected syntax and visual aesthetics. While `()` is more commonly associated with function calls and grouping expressions, `[]` is often associated with array indexing or indexing-like operations. + + - title: Encapsulation With Methods code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=struct%20SeaCreature%20%7B%0A%20%20%20%20noise%3A%20String%2C%0A%7D%0A%0Aimpl%20SeaCreature%20%7B%0A%20%20%20%20fn%20get_sound(%26self)%20-%3E%20%26str%20%7B%0A%20%20%20%20%20%20%20%20%26self.noise%0A%20%20%20%20%7D%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20let%20creature%20%3D%20SeaCreature%20%7B%0A%20%20%20%20%20%20%20%20noise%3A%20String%3A%3Afrom(%22blub%22)%2C%0A%20%20%20%20%7D%3B%0A%20%20%20%20println!(%22%7B%7D%22%2C%20creature.get_sound())%3B%0A%7D%0A diff --git a/lessons/en/chapter_8.yaml b/lessons/en/chapter_8.yaml index 79290ad46..c56230e05 100644 --- a/lessons/en/chapter_8.yaml +++ b/lessons/en/chapter_8.yaml @@ -26,6 +26,55 @@ will validate the lifetime of references doesn't last longer than what it refers to (otherwise we'd get an error when we used it!). +- title: What is a pointer? + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=fn+main%28%29+%7B%0A++++let+a%3A+i32+%3D+12i32%3B%0A++++let+b%3A+%26i32+%3D+%26a%3B+++%2F%2F+pointer+to+i32%0A++++let+c%3A+%26%26i32+%3D+%26b%3B++%2F%2F+pointer+to+pointer+to+i32%0A++++let+d%3A+%26%26%26i32+%3D+%26c%3B%09%2F%2F+pointer+to+pointer+to+pointer+to+i32%0A++++%0A++++println%21%28%22%7B%7D+%7B%7D+%7B%7D+%7B%7D%22%2C+a%2C+b%2C+c%2C+d%29%3B%0A++++println%21%28%22%7B%7D+%7B%7D+%7B%7D+%7B%7D%22%2C+a%2C+*b%2C+**c%2C+***d%29%3B%0A%7D%0A + content_markdown: > + A pointer is a variable. + + Each variable: + - has a name + - has a data type + - has an address (in the RAM memory) + - stores an value + + Why do use data types? + + By using data types, we basically tell the CPU how much memory to + allocate for the variables we declare. For instance, the compiler + allocates 8 bytes for each `i8` and `u8` variable. Without pointers, a variables stores a `value`. + + You've seen `u16`, `f64`, `usize`. These are data types. + So are `&i32`, `&&i32` `&&&i32` and so on. + + The same logic applies to pointers. A pointer is a data type itself and + when we use pointer, the variables stores the `address` of the variable + instead of `value`. For pointer, the stored `value` is an `address`. + + + | variable name | data type | address | stored value | + | ------------- | --------- | ------- | --------------- | + | a | i32 | 0x100 | 12 | + | b = &a | &i32 | 0x132 | 0x100 (addr) | + | c = &b | &&i32 | 0x2a1 | 0x132 (addr) | + | d = &c | &&&i32 | 0x712 | 0x2a1 (addr) | + + > The CPU chooses the address of a variable at runtime + > Do not expect to have the same address at different executions + + All variables `i32`, `&i32`, `&&i32`, `&&&i32` are 32-bit variable. + + `i32` -> stores a concrete value + `&...&i32` -> stores an address + + + However, when you try to print references (like `&i32`, `&&i32`, `&&&i32`), + Rust automatically `dereferences` them when using the `{}` format specifier in a `println!` `macro`. This means that the `values` themselves are + printed, not their `addresses`. + + [![Pointer](https://i.redd.it/swszegbgpbr71.jpg) + This is for `C`. + For Rust, think that `int` is `u128`, and `*` is Rust's `&`. - title: Raw Pointers code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20let%20a%20%3D%2042%3B%0A%20%20%20%20let%20memory_location%20%3D%20%26a%20as%20*const%20i32%20as%20usize%3B%0A%20%20%20%20println!(%22Data%20is%20here%20%7B%7D%22%2C%20memory_location)%3B%0A%7D%0A diff --git a/lessons/en/chapter_9.yaml b/lessons/en/chapter_9.yaml index ee8cb9e16..43bebd26f 100644 --- a/lessons/en/chapter_9.yaml +++ b/lessons/en/chapter_9.yaml @@ -2,6 +2,27 @@ content_markdown: > So far all of our code examples have been a single file. Let's discuss how our code can be better organized and shared by others! +- title: Cargo + content_markdown: > + `Cargo` is the official Rust package management tool for `crates`. + It helps us organise code in more than one file. + + Rust programs may contain a `binary crate` (an executable, + for instance `./main`) or a `library crate` (a collection of functions, + data types, structs, trait and so on). You've already used a library in + writing code, which is `std` (the standard Rust library). + + + Therefore, there are two type of crates in Rust: + - `binary crates` : contain a `main.rs` file + - `library crates` : contain a `lib.rs` file + + A `crate` cannot have both `main.rs` and `lib.rs`. + + ![crates](https://raw.githubusercontent.com/kannans89/RustRepo/master/Images/movie_lib.jpg) + + Resources: + - [https://youtu.be/969j0qnJGi8](https://youtu.be/969j0qnJGi8) - title: Modules content_markdown: | Every Rust program or library is a *crate*. @@ -13,12 +34,115 @@ A module can hold global variables, functions, structs, traits or even other modules! In Rust there is not a 1 to 1 mapping of files to the module tree hierarchy. We must build the module tree explicitly by hand in our code. + + + More information about how to split you code in different files / moduels + can be found [here](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/crates-and-modules.html). - title: Writing a Program content_markdown: | A program has a root module in a file called `main.rs`. +- title: Binary Crate + content_markdown: | + For a `binary crate`, `cargo` has the following terminal commands: + + ``` + $ cargo new my-first-binary-crates # creates a binary create + $ cd my-first-binary-crates/ + $ cargo build # equivalent of `rustc main.rs` + $ cargo run # equivalent of `./main` + ``` + + If you inspect the file hierarchy system, you'll notice that `cargo` + automatically creates some files and folders, and also writes some code. + Cool! + + A `binary crate` will depend on the `main.rs`. + Btw, do not try to create a `lib.rs` here. + Our friend `cargo` will be confused. + - title: Writing a Library content_markdown: | A library has a root module in a file called `lib.rs`. +- title: Library Crate + content_markdown: | + `cargo` has the following terminal commands for a `library crate` : + + ``` + $ cargo new --lib my-first-library # creates a library crate + $ cd my-first-library/ + $ cargo build # links the dependencies between files (modules) + $ cargo test # checks the unit tests + ``` + + Unlike other Rust executable files you've written before, + a `library` contains functions and data types that are meant to be `used` + in other programs, in order to simplify some abstractions. + + Think about the C `#include `. It is a library: it offers access + to functions, variables and even more. That's what a library is meant for. +- title: Testing My Library + content_markdown: > + Rust libraries have a `lib.rs`, where you can test functionality of your + library. + + When creating one, `cargo` helps you by creating some code: + ```rust + pub fn add(left: usize, right: usize) -> usize { + left + right + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } + } + + ``` + + + If you need more tests, create functions annotated with `#[test]`. + Each function should use the macro `assert_eq!` or `assert!`. + Use this macro only once, since it exits the function once it is executed. + + `lib.rs`: + + ``` + pub fn add(left: usize, right: usize) -> usize { + left + right + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } + + #[test] + fn add_zero() { + // Test if adding 0 to any number returns the same number + let result = add(5, 0); + assert_eq!(result, 5); + assert_eq!(result, 10); // this line will not be executed :) + } + } + + ``` + + + Test everything you create. + + + You can find [here](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/testing.html) + more about [testing](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/testing.html). - title: Referencing Other Modules and Crates code: >- https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use%20std%3A%3Af64%3A%3Aconsts%3A%3API%3B%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Welcome%20to%20the%20playground!%22)%3B%0A%20%20%20%20println!(%22I%20would%20love%20a%20slice%20of%20%7B%7D!%22%2C%20PI)%3B%0A%7D%0A @@ -130,6 +254,26 @@ a crate accessible by marking them as `pub` in the *root module* of your crate (`lib.rs` or `main.rs`). +- title: use + content_markdown: > + The `use` keyword has the purpose of bringing symbols into scope. + + It allows you to use functions, structs or traits from a `module` + without using the full path each time. + + The Rust `use` is equivalent to Python's `import` if we are to make + a comparison between these two programming languages. + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=%2F%2F+Bringing+the+%60println%60+function+into+scope%0Ause+std%3A%3Aio%3A%3Aprintln%3B%0A%0Afn+main%28%29+%7B%0A++++println%21%28%22Hello%2C+World%21%22%29%3B%0A%7D%0A +- title: extern crate + content_markdown: > + The `extern crate` directive was used in older versions of Rust (before the 2018 edition). + + Now, it is no longer required to use `extern crate` in code. + + Instead, we specify the dependence on external crates in the `Cargo.toml` file + code: >- + https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&code=extern+crate+rand%3B%0A%0Afn+main%28%29+%7B%0A++++let+random_number+%3D+rand%3A%3Arandom%3A%3A%3Cu32%3E%28%29%3B%0A++++println%21%28%22Random+number%3A+%7B%7D%22%2C+random_number%29%3B%0A%7D%0A - title: Structure Visibility content_markdown: > Just like functions, structures can declare what they want exposed outside