Typo/grammar fixes plus copy edits for Rust roadmap (19 files) (#5906)
* Fix typos Rust/100-integers.md * Grammatical clarity Rust/101-why-rust.md * Sentence restructuring for Rust/102-memory-safety.md * Additional linker explanation for newbies, Rust/103-installing-rust.md * Wording changes, Rust/103-installing-rust.md * "tools for debugging" -> "debugging tools" Rust/104-ides-and-rust.md * Small clarity change Rust/105-rust-repl.md * "systems" -> "system" (for consistency), Rust/101-why-rust.md * Clarity, Rust/101-variables.md * Small sentence edits, Rust/102-control-flow.md * Another small edit, 102-control-flow.md * Small changes + added `return` keyword info, Rust/103-functions.md * Rust/103-functions.md * Clarity/grammar for Rust/104-pattern-matching.md * Sentence flow + prose about pattern matching, Rust/100-syntax/index.md * Wording/paragraph improvements, Rust/100-syntax/index.md * List-ified, italics-ified for Rust/101-ownership/100-rules.md * Small changes + bullets for Rust/102-stack-heap.md * List-ify + small clarity improvements, Rust/101-ownership/index.md * Sentence flow & clarity for Rust/102-constructs/100-enums.md * Rewrite of Rust/100-enums.md * a -> an * List-ify and small edits for Rust/101-structs.md * Bold some stuff in Rust/101-structs.md * Small rewrite for Rust/102-traits.md * Rewrite Rust/103-impl-blocks.md * List-ify + clarity edits for Rust/102-constructs/index.md * More data types explanation for Rust/102-constructs/index.md * define -> declare * Update index.md * Unbolded “traits” * Unbolded “enum” + replaced em-dashes with commas * “Rust is a system…” * Replaced em-dashes with commas * Update 102-control-flow.md Replaced more em-dashes with commas * Unbold “struct” * Unbold “constructs”pull/5915/head
parent
2da1f61945
commit
64bbbc2f25
19 changed files with 77 additions and 31 deletions
@ -1,7 +1,7 @@ |
||||
# Memory Safety and Zero-Cost Abstractions |
||||
|
||||
Rust, a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. It is graced with the feature of "memory safety without garbage collection", an attribute that makes Rust one of its kind. Memory safety is ensuring that software, while accessing the system's memory, is not causing any leaks, or dangling pointers. In Rust, memory safety is accomplished through a system of ownership with a set of rules that the compiler checks at compile time. This system eliminates the need of garbage collection or manual memory management, hence ensuring swift execution of software along with a safer memory environment. This memory management feature in Rust even provides concurrent programming guaranteeing thread safety with options for shared and mutable state access that makes it harder to cause thread unsafety. |
||||
Rust is a system programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. It is graced with the feature of "memory safety without garbage collection," an attribute that makes Rust one of a kind. "Memory safety" is ensuring that software is not causing any memory leaks or dangling pointers while accessing the system's memory. In Rust, memory safety is accomplished through a system called ownership, with a set of rules that the compiler checks at compile time. This ownership system eliminates the need for garbage collection or manual memory management, thus ensuring swift execution of software and a safer memory environment. Rust's memory management features even support concurrent programming, providing options for shared and mutable state access that ensure thread safety while reducing the risk of thread unsafety. |
||||
|
||||
<!-- Adding content on Zero-cost Abstraction --> |
||||
|
||||
Zero cost abstraction is another key feature of Rust. In general, abstractions in programming languages allow code to be written at a high level (like in Python), while being able to run at a low level (like in C). However, these abstractions often come with a runtime cost. Rust aims to provide abstractions that are as fast as writing the code manually at a low level. This means you can write high-level code, and the Rust compiler will optimize it to run as fast as manually written low-level code. |
||||
Zero-cost abstraction is another key concept Rust implements. In general, abstractions in programming languages allow code to be written at a high level (like in Python), while being able to run at a low level (like in C). However, these abstractions often come with a runtime cost. In contrast, Rust aims to provide many useful abstractions, such as iterators and closures, that don't sacrifice runtime performance. This means you can write high-level code in Rust, and the Rust compiler will optimize it to run as fast as manually written low-level code. |
||||
|
@ -1,3 +1,7 @@ |
||||
# Installing Rust and Cargo |
||||
|
||||
To install Rust, navigate to the official website at [https://www.rust-lang.org](https://www.rust-lang.org) and download the appropriate installation file for your operating system. For UNIX systems like Linux and MacOS, installation is as easy as running a single command in the terminal. For Windows, you'll be provided with a '.exe' installer which you need to execute. Further instructions can be found on the download page of the website. Keep in mind that you'll also need a linker of your operating system such as 'gcc'. You can update your Rust version at any time by running `rustup update` in the terminal. |
||||
To install Rust, navigate to the official website at [https://www.rust-lang.org](https://www.rust-lang.org) and download the appropriate installation file (or run the appropriate terminal command) for your operating system. You'll be installing `rustup`, which is the preferred tool for installing, updating, and managing your core Rust tooling. For UNIX systems like Linux and MacOS, installation is as easy as running a single command in the terminal. For Windows, you'll be provided with an '.exe' installer which you need to execute. Further instructions can be found on the download page of the website. |
||||
|
||||
Keep in mind that for the compiler to create executables, you'll also need a linker on your operating system, such as 'GCC'. Otherwise, you'll encounter errors when you try to run `rustc` or `cargo`. This is one necessary thing that `rustup` doesn't install for you. Such linker components are part of the C standard library, so they may or may not be partially or fully preinstalled on your system. For example, a common error when running `rustc` for the first time in a 64-bit Linux environment is that your system is missing 32-bit support for GCC, which can be solved by installing `gcc-multilib`. |
||||
|
||||
You can update your Rust version at any time by running `rustup update` in the terminal. |
||||
|
@ -1,3 +1,3 @@ |
||||
# IDEs and Rust Toolchains |
||||
|
||||
For the Rust Programming Language, several Integrated Development Environments (IDEs) and editors provide great support. [Visual Studio Code](https://code.visualstudio.com) is highly preferred among Rust developers due to its support for Rust via the "Rust Language Server" or "rust-analyzer" plugins. Another popular choice is [RustRover](https://www.jetbrains.com/rust/), a dedicated IDE for Rust development by JetBrains. Additionally, [Sublime Text](https://www.sublimetext.com) and [Atom](https://atom.io) with respective Rust-enhancement plugins are also used. For a more terminal-centric approach, [Vim](https://www.vim.org) and [Emacs](https://www.gnu.org/software/emacs/) are equipped with Rust modes. These IDEs and editors offer various features like auto-completion, syntax highlighting, and tools for debugging which prove useful for Rust programming. |
||||
For the Rust Programming Language, several Integrated Development Environments (IDEs) and editors provide great support. [Visual Studio Code](https://code.visualstudio.com) is highly preferred among Rust developers due to its support for Rust via the "Rust Language Server" or "rust-analyzer" plugins. Another popular choice is [RustRover](https://www.jetbrains.com/rust/), a dedicated IDE for Rust development by JetBrains. Additionally, [Sublime Text](https://www.sublimetext.com) and [Atom](https://atom.io) with respective Rust-enhancement plugins are also used. For a more terminal-centric approach, [Vim](https://www.vim.org) and [Emacs](https://www.gnu.org/software/emacs/) are equipped with Rust modes. These IDEs and editors offer various features like auto-completion, syntax highlighting, and debugging tools which prove useful for Rust programming. |
||||
|
@ -1,3 +1,3 @@ |
||||
# Rust REPL (Rust Playground) |
||||
|
||||
`Rust REPL` (Read-Eval-Print-Loop) is an interactive shell in which you can write and test Rust snippets in real-time. Unlike running a program normally in Rust where you have to manually compile and then run the program, in REPL the inputs are automatically evaluated, and the result is returned immediately after execution. This is helpful when experimenting with Rust code, learning the language, and debugging. REPL isn't built into Rust directly but is available via third-party tools such as `evcxr_repl`. |
||||
`Rust REPL` (Read-Eval-Print-Loop) is an interactive shell in which you can write and test Rust snippets in real-time. Unlike running a program normally in Rust where you have to manually compile and then run the program, REPL automatically evaluates your inputs, and the result is returned immediately after execution. This is helpful when experimenting with Rust code, learning the language, and debugging. REPL isn't built into Rust directly, but is available via third-party tools such as `evcxr_repl`. |
||||
|
@ -1,7 +1,7 @@ |
||||
# Control Flow Constructs |
||||
|
||||
In Rust, control flow is managed through various structures like `if`, `else`, `while`, `for`, and `match`. The `if` and `else` structures are used to execute different blocks of code based on certain conditions. Similar to other languages, `while` and `for` are used for looping over a block of code. The `while` loop repeats a block of code until the condition is false, and the `for` loop is used to iterate over a collection of values like an array or a range. The `match` structure is a powerful tool in Rust which can be used for pattern matching. It goes through different cases and executes the block where the match is found. |
||||
In Rust, control flow is managed through various structures, like `if`, `else`, `while`, `for`, and `match`. The `if` and `else` structures are used to execute different blocks of code based on certain conditions. Similar to other languages, `while` and `for` are used for looping over a block of code. The `while` loop repeats a block of code until the condition is false, and the `for` loop is used to iterate over a collection of values, such as an array or a range. Rust's `match` structure, which is similar to switch statements in other languages, is a powerful tool used for pattern matching: it checks through different cases defined by the programmer and executes the block where the match is found. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@Control Flow](https://rust-book.cs.brown.edu/ch03-05-control-flow.html) |
||||
- [@article@Control Flow](https://rust-book.cs.brown.edu/ch03-05-control-flow.html) |
||||
|
@ -1,7 +1,9 @@ |
||||
# Functions and Method Syntax |
||||
Functions and Method Syntax |
||||
|
||||
In Rust, functions are declared using the `fn` keyword. Each function takes a set of input variables with their specified types and may optionally return a type. The body of the function is contained within curly braces `{}`. Unlike other languages, in Rust you don't need to end the statement with a semicolon if it’s the last one in a block, making it the implicit return. If we want to return a value, we simply write the expression we want to return. An example of a function in Rust is `fn add(one: i32, two: i32) -> i32 { one + two }` where `one` and `two` are parameters of type `i32` and the function returns an integer of type `i32`. |
||||
In Rust, functions are declared using the `fn` keyword. Each function can take a set of input variables with their specified types, and may return data of a specified type. The body of a function is contained within curly braces `{}`. Unlike other languages, in Rust, you don't need to end the last statement in a block with a semicolon; omitting the last semicolon of a block in this way turns the last statement into an expression, and the result of this expression becomes the implicit return value of the block. In other words, if we want to return a value, we simply write the expression we want to return. |
||||
|
||||
An example of a function that returns implicitly in Rust is `fn add(one: i32, two: i32) -> i32 { one + two }`, where `one` and `two` are parameters of type `i32`. This function returns an integer of type `i32`, which is the result of `one + two`. Rust also has an explicit `return` keyword to exit a function with a given value, like so: `fn add(one: i32, two: i32) -> i32 { return one + two; }`. Using a `return` statement versus the implicit return syntax is mostly a matter of preference. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@Functions](https://rust-book.cs.brown.edu/ch03-03-how-functions-work.html) |
||||
- [@article@Functions](https://rust-book.cs.brown.edu/ch03-03-how-functions-work.html) |
||||
|
@ -1,8 +1,8 @@ |
||||
# Pattern Matching and Destructuring |
||||
|
||||
In Rust, `pattern matching` is a robust tool that allows you to destructure data types and perform conditional checks in a succinct and clear way. The main structures used for pattern matching are `match` and `if let`. The `match` keyword can be used to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things. The `if let` allows you to combine `if` and `let` into a less verbose way to handle values that match a specific pattern. It's basically a nice syntax sugar over a `match` statement. |
||||
In Rust, "pattern matching" is a robust tool that allows you to destructure data types and perform conditional checks in a succinct and clear way. The main structures used for pattern matching are `match` and `if let`. The `match` keyword can be used to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things. The `if let` structure allows you to combine `if` and `let` into a less verbose way of handling values that match one specific pattern, rather than a series of patterns. It's basically a nice syntax sugar over a `match` statement. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@The match Control Flow Construct](https://rust-book.cs.brown.edu/ch06-02-match.html) |
||||
- [@article@Concise Control Flow with if let](https://rust-book.cs.brown.edu/ch06-03-if-let.html) |
||||
- [@article@Concise Control Flow with if let](https://rust-book.cs.brown.edu/ch06-03-if-let.html) |
||||
|
@ -1,3 +1,7 @@ |
||||
# Syntax and Semantics |
||||
|
||||
Rust's syntax aims for readability and avoids visual clutter. It places a great deal of importance on forward compatibility, even when it occasionally hinders feature additions. Most Rust syntax is based on the same basic principles. Understanding a handful of concepts allows a broad understanding of the structure of most Rust programs. Some of these concepts include item declarations and pattern matching. In Rust, you typically declare an item once and then refer to it by its name. Pattern matching is a fundamental and powerful part of Rust’s syntax, allowing you to branch your code based on the structure of data, not just its value or type. |
||||
Rust's syntax aims for readability and reduced visual clutter. Rust also places a great deal of importance on forward compatibility, even when it occasionally hinders feature additions. |
||||
|
||||
Most syntax in Rust is built around the same basic principles, so understanding a handful of Rust's core concepts allows for a broad understanding of the structure of most Rust programs. Examples of Rust's most widely-used syntactic components are item declarations and pattern matching. In Rust, you typically declare an item once and then refer to it by its name as long as it's in scope. Pattern matching is a fundamental and powerful part of Rust's syntax: it allows you to branch code based on the structure of its data, not just its value or type. |
||||
|
||||
It takes time to learn all of Rust's paradigms for constructing the most robust and elegant pattern matching (e.g., by implementing your own data types). However, even complex pattern matching can be intuitive to read and concise, which is what makes it so powerful. |
||||
|
@ -1,7 +1,10 @@ |
||||
# Ownership Rules and Memory Safety |
||||
|
||||
In Rust, the concept of ownership is described by three main rules. Firstly, each value in Rust has a variable that is called its owner. Secondly, there can only ever be one owner at a time. This prevents multiple parts of the code from trying to modify the data at once, potentially causing data races and inconsistencies. Lastly, when the owner goes out of scope, the value will be dropped. This ensures that Rust cleans up the allocated memory and other resources once they’re no longer required, thereby avoiding memory leaks. |
||||
In Rust, the concept of ownership is described by three main rules. |
||||
1. Each value in Rust has a variable that is called its _owner_. |
||||
2. There can only ever be _one owner at a time_. This prevents multiple parts of the code from trying to modify the data at once, potentially causing data races and inconsistencies. |
||||
3. _When the owner goes out of scope, the value will be dropped_. This ensures that Rust cleans up the allocated memory and other resources once they're no longer required, thereby avoiding memory leaks. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@What Is Ownership?](https://rust-book.cs.brown.edu/ch04-01-what-is-ownership.html) |
||||
- [@article@What Is Ownership?](https://rust-book.cs.brown.edu/ch04-01-what-is-ownership.html) |
||||
|
@ -1,7 +1,13 @@ |
||||
# Deep Dive: Stack vs Heap |
||||
|
||||
In most modern computer systems, memory management is split into two main parts: the stack and the heap. The **stack** is a section of memory that grows and shrinks automatically as functions are called and return. The data stored on the stack must have a known, fixed size. The **heap** is a section of memory that is used for data that needs to persist for longer than a single function-call. Data with dynamic size is stored on the heap. Rust, like many languages, has facilities for using these two types of memory, allowing developers fine-tuned control over memory usage. |
||||
In most modern computer systems, memory management is split into two main parts: the stack and the heap. |
||||
|
||||
- The **stack** is a section of memory that grows and shrinks automatically as functions are called and return. For data to be stored on the stack, it must have a known, fixed size at compile time. |
||||
|
||||
- The **heap** is a section of memory that is used for data that needs to persist for longer than a single function-call. Data with dynamic size is stored on the heap. |
||||
|
||||
Rust, like many languages, has facilities for using these two types of memory, allowing developers fine-tuned control over memory usage. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@The Stack and the Heap](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/the-stack-and-the-heap.html) |
||||
- [@article@The Stack and the Heap](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/first-edition/the-stack-and-the-heap.html) |
||||
|
@ -1,3 +1,7 @@ |
||||
# Ownership System |
||||
|
||||
In Rust, the concept of `Ownership` is a key feature that governs how memory management works. Each value in Rust has its own designated owner and there can be only one owner for a value at a time. When the owner goes out of scope, the value would be automatically dropped. The three main facets of ownership include ownership rules, `borrowing` and `slices`. Ownership rules play a key role in system performance and prevention of issues like null or dangling references. `Borrowing` is a mechanism where we allow something to reference a value without taking ownership. Finally, `slices` are a data type that does not have ownership and helps in making a reference to a portion of a collection. |
||||
In Rust, the concept of **ownership** is a key feature that governs how memory management works. Each value in Rust has its own designated "owner," and there can be only one owner for a value at a time. When the owner goes out of scope, whatever value it owns is automatically _dropped_ from memory. The three main facets of ownership include ownership rules, borrowing, and slices. |
||||
|
||||
- **Ownership rules** play a key role in system performance and prevention of issues, such as null or dangling references. |
||||
- **Borrowing** is a mechanism where we allow something to _reference_ a value without taking _ownership_. |
||||
- **Slices** are a data type that does _not_ have ownership. Specifically, slices help in making a reference to a portion of a collection data type, like a `String`, `Array`, or `Vec`. |
||||
|
@ -1,7 +1,13 @@ |
||||
# Structs |
||||
|
||||
In Rust, `struct` is a custom data type used for grouping related values together into one entity. It is similar to classes in other programming languages. Essentially, they create a new type that we can use to streamline complex data handling. There are three types of `struct` in Rust - classic `C` structs, tuple structs, and unit structs. Classic `C` structs are named-field struct and are the most commonly used. Tuple struct, while not being common, are useful when you want to couple together a few data points. Unit structs are useful in situations where you want to implement a trait on some type but don’t have any data that you want to store in the type itself. |
||||
In Rust, a struct is a custom data type used for grouping related values together into one entity. Structs are similar to classes in other programming languages. Essentially, each `struct` creates a new type that we can use to streamline complex data handling. |
||||
|
||||
There are three types of `struct` in Rust: classic 'C' structs, tuple structs, and unit structs. |
||||
|
||||
- **Classic 'C' structs** are named-field structs and are the most commonly used. |
||||
- **Tuple structs**, while not being common, are useful when you want to couple together just a few data points that don't need field names. |
||||
- **Unit structs** are useful in situations where you want to implement a **trait** on some type, but don't have any data that you want to store in the type itself. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@Defining and Instantiating Structs](https://rust-book.cs.brown.edu/ch05-01-defining-structs.html) |
||||
- [@article@Defining and Instantiating Structs](https://rust-book.cs.brown.edu/ch05-01-defining-structs.html) |
||||
|
@ -1,7 +1,11 @@ |
||||
# Traits |
||||
|
||||
Traits in Rust programming language define shared behaviors. They are a way to group method signatures together to define a set of behaviors required by a type. Anything with a certain trait will have the behavior of that trait's methods. Traits are abstract, and it's not possible as such to create instances of traits. However, we can define pointers of trait types, and these can hold any implementer of the trait. A trait is implemented for something else, which can be a concrete type or another trait. |
||||
Traits in Rust define behaviors that are shared among different data types. Implementing traits for data types is a great way to group method signatures together and define a set of behaviors your types require. Essentially, anything with a certain `trait` applied to it will "inherit" the behavior of that trait's methods, but this is not the same thing as inheritance found in object-oriented programming languages. |
||||
|
||||
Traits are abstract; it's not possible to create instances of traits. However, we can define pointers of trait types, and these can hold any data type that implements the `trait`. A `trait` is **implemented** for something else with the syntax `impl TraitAbc for Xyz {...}`, which can be a concrete type or another trait. |
||||
|
||||
You should read carefully about traits in Rust and understand how some common traits, like `Copy`, are already implemented for various primitive types and how this could affect your program. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@Traits: Defining Shared Behaviour](https://doc.rust-lang.org/book/ch10-02-traits.html) |
||||
- [@article@Traits: Defining Shared Behaviour](https://doc.rust-lang.org/book/ch10-02-traits.html) |
||||
|
@ -1,7 +1,9 @@ |
||||
# Impl Blocks |
||||
|
||||
Impl Block in rust is used to implement a trait or a struct. It is used to define the behavior of a trait or a struct. |
||||
Impl blocks use the `impl` keyword, and are used to **implement** behavior in the form of **methods** for a `struct`, `enum`, or `trait`. If you want your data type or trait to have methods, you need a corresponding `impl` block containing functions for the type or trait. |
||||
|
||||
Note that `self` and `Self` have different meanings in the context of an `impl` block's functions. `self` represents the specific value in your program that's calling the method and passing itself as an argument, while `Self` is syntax sugar for the `impl` block's data type, which is commonly used in constructor methods that return a new instance of the type. |
||||
|
||||
Learn more from the following links: |
||||
|
||||
- [@article@Method Syntax](https://rust-book.cs.brown.edu/ch05-03-method-syntax.html) |
||||
- [@article@Method Syntax](https://rust-book.cs.brown.edu/ch05-03-method-syntax.html) |
||||
|
@ -1,3 +1,10 @@ |
||||
# Constructs |
||||
|
||||
In Rust, "constructs" refer to different elements used to build the structure of the program. This includes variables, functions, data types, control flow statements, and more. **Variables** store data, and their mutable or immutable status is determined at their declaration. **Functions** are reusable blocks of code defined by the `fn` keyword. Data types in Rust are static and must be declared upfront. These include simple ones like integers, boolean, float, etc, and complex types like arrays, tuples etc. **Control Flow** structures help direct the flow of execution. These include `if`, `else`, `loop`, `while`, `for`, and more. Exception handling uses the `Result` and `Option` enums along with the `match` construct. Rust's constructs like these come together to structure your program in a safe yet efficient manner. |
||||
In Rust, "constructs" refer to different elements used to build the structure of the program. Constructs includes variables, functions, data types, control flow statements, and more. |
||||
|
||||
- **Variables** store data, and their immutable or mutable status is determined at their declaration with `let` and `let mut`, respectively. |
||||
- **Functions** are reusable blocks of code defined by the `fn` keyword. |
||||
- **Data types** in Rust are static and must be declared upfront. These include simple _primitive_ types, like integers, booleans (`bool`), and floats, as well as _complex_ types like arrays, tuples, all the custom types you declare yourself, and many more types you might use from Rust's standard library or community crates you download. |
||||
- **Control flow** structures help direct the flow of code execution. These include `if`, `else`, `loop`, `while`, and `for` blocks, to name a few. Exception handling in Rust leverages the `Result<T, E>` and `Option<T>` enums alongside the `match` construct's ability to perform concise pattern matching. |
||||
|
||||
As a Rust programmer, you'll utilize many of the language's constructs like the ones above. These pieces come together at your fingertips to structure your program in a safe and efficient manner. |
||||
|
Loading…
Reference in new issue