Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

English version of WTF-Rust (1-5) #23

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Languages/en/01_HelloRust/hello_cargo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[profile.dev]
debug = true # Include debug info
opt-level = 0 # No optimization
3 changes: 3 additions & 0 deletions Languages/en/01_HelloRust/hello_cargo/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, rust!");
}
Binary file added Languages/en/01_HelloRust/imgs/img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 112 additions & 0 deletions Languages/en/01_HelloRust/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: 1. Hello Rust
tags:
- Rust
- Install
- Cargo
- wtfacademy
---

# WTF Rust Minimalist Introduction: 1. Hello Rust

I am recently relearning `Rust` to solidify the details and to write a `WTF Rust Minimalist Introduction` for beginners (advanced programmers can find other tutorials). I will update it 1-3 times per week.

## Introduction to Rust

`Rust` is a systems programming language developed by Mozilla Research, focusing on safety, speed, and concurrency. It aims to help developers build reliable, efficient software systems while preventing common security vulnerabilities, such as null pointer dereferences and buffer overflows.

The design principles of `Rust` include zero-cost abstractions, guaranteed memory safety, data-race-free concurrency, and pragmatism. Through mechanisms like ownership, borrowing, and lifetimes, it ensures memory safety while avoiding the performance overhead of garbage collection.

## Installing Rust

First, we need to install `Rust` on your machine. `Rust` has a fantastic installation tool called `rustup`, which helps us manage `Rust` versions and the corresponding toolchains. Let's install it!

On `macOS`, `Linux`, or Unix-like operating systems, install using the following command:

Open your terminal (or command line) and enter the following command:

```Bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

This command will download a script and execute it. The script will automatically install `rustup` and the default version of Rust (including `rustc`, the Rust compiler, and `cargo`, the Rust package manager). Follow the instructions in the terminal, and once everything is set up, we can proceed to the next step!

After installation is complete, you can check the Rust version by running the `rustc --version` command to verify if the installation was successful. If it indicates that `rustc` cannot be found, it is an environment variable issue. Check whether the directory `~/.cargo/bin` has been added to `PATH`. You can restart the terminal or manually source it to apply the environment changes.

If it is the `Windows` system, please refer to [Official Installation Instructions](https://forge.rust-lang.org/infra/other-installation-methods.html)

## Hello Rust program

In the journey of programming language, the program is the first step of the traditional. It is the simplest program that "ask well" to the world. It is no exception in Rust, let's try it!

1. Create a new folder, named `Hello_rust`, and then enter this folder.
2. In the `Hello_rust` folder, create a new file, named` main.rs`. The file name `.s` suffix represents a RUST source file.
3. Open the `main.rs`, use your favorite text editor, enter the following code:

```rust
fn main () {
Println! ("Hello, Rust!");
}
```

To explain briefly, this code defines a function `main`, which is the entrance point of each Rust program. When the Rust program runs, it executes the code in the `main` function. `Println!` is a macro (we talk about macro in the future), used to output text to the terminal.

4. Save the file and return to the terminal to make sure you are in the `Hello_rust` folder, and then enter the following command to compile and run your program:

```Bash
Rustc Main.rs
./main
```

If you are a user, the command of the running program may be slightly different, such as entering the `main` directly.

If everything goes well, your terminal will output:

```
Hello, Rust!
```

Congratulations, you have successfully run your first Rust program!

## Use Cargo

In Rust's world, `Cargo` is your good friend. It is not only a bag management tool, but also helps you build projects, download dependencies, run tests, and so on. Let's take a look at how to use the `Cargo` to create and run a new project.

1. Open the terminal and enter the following command to create a new RUST project:

```Bash
Cargo new hello_cargo
```

This command will create a new folder called `Hello_cargo`, which contains a preliminary project structure.

2. Enter the `Hello_cargo` folder, you will find that there are two main files:` cargo.toml` and `src/main.rs`. `Cargo.toml` is your project configuration file, while` src/main.rs` is your main program file, which has the default `Hello, Rust!` Code.

3. Let's compile and run the project directly to see the magic of `Cargo`! In the terminal of the `hello_cargo` folder, enter the following command:

```Bash
Cargo run
```

`Cargo Run` command will automatically compile your code (if necessary) and run the generated program. You should see the greetings of `Hello, Rust!` In the terminal.


4. If you use Rustrover, you can directly run the program directly in the `Cargo` plug -in that comes with your own` Cargo` plug -in to facilitate the rapid verification of the program.

![img.png](imgs/img.png)

5. In the demonstration code in the subsequent chapters, I will use `Cargo` to demonstrate, so that everyone will run and test.

that's all! Now, you already know how to install the `Rust`, write and run the` Rust` program, and use the simple item to manage the `Cargo`. This is just the tip of the iceberg. The world of `Rust` is full of possibilities and adventures waiting for you. Are you ready? Let's move forward and go deep into the wonderful journey of `Rust`!

## Summary

This chapter mainly introduces the `Rust` installation method, write the first` Rust` program --`hello Rust`, and introduce how to use `Cargo` for project development








8 changes: 8 additions & 0 deletions Languages/en/02_BaseType/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "base_type"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
145 changes: 145 additions & 0 deletions Languages/en/02_BaseType/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
title: 2. Base Type
tags:
- Rust
- Variables
- wtfacademy
---

# WTF Rust Minimalist Introduction: Base Types

In this chapter, we will explore the basic syntax elements in Rust through examples with detailed explanations. We will cover variables and mutability, as well as data types (including scalar and compound types).

## Variables and Mutability

In Rust, variables are immutable by default. This means that once a value is assigned to a variable, you cannot change it. However, you can use the `mut` keyword to make a variable mutable.

### Immutable Variables

```rust
let x = 5;
println!("The value of x is: {}", x);
// x = 6; // This line will cause a compile error because x is immutable
```

### Mutable Variables

```rust
let mut y = 5;
println!("The value of y is: {}", y);
y = 6; // This is allowed because y is mutable
println!("The value of y is: {}", y);
```

## Data Types

Rust is a statically typed language, meaning all variable types must be known at compile time. The compiler usually infers types based on values and usage. Rust data types can be broadly divided into two categories: scalar and compound types.

### Scalar Types

Scalar types represent single values. As previously mentioned, Rust has four primary scalar types: integers, floating-point numbers, booleans, and characters.

#### Integers

Integers are numbers without fractional parts. In Rust, integer types are divided into signed and unsigned. For example, the `i32` type represents a signed 32-bit integer (`i` stands for `integer`). The `u` prefix indicates an unsigned type. Here are the built-in integer types available in Rust:

| Length | Signed Type | Unsigned Type |
|:------------:|:-----------:|:-------------:|
| 8-bit | `i8` | `u8` |
| 16-bit | `i16` | `u16` |
| 32-bit | `i32` | `u32` |
| 64-bit | `i64` | `u64` |
| 128-bit | `i128` | `u128` |
| Architecture | `isize` | `usize` |

For signed types, the numeric range is from `-(2^(n-1))` to `2^(n-1) - 1`, where `n` is the number of bits. For example, `i8` can store values from `-128` to `127`. Unsigned types range from `0` to `2^n - 1`, so `u8` ranges from `0` to `255`.

The size of `isize` and `usize` depends on the architecture of the computer running the program: 32 bits for 32-bit CPUs and 64 bits for 64-bit CPUs.

Integer literals can be represented in several ways:

- Decimal: without a prefix, e.g., 98_222 (underscores improve readability)
- Hexadecimal: with a `0x` prefix, e.g., 0xff
- Octal: with a `0o` prefix, e.g., 0o77
- Binary: with a `0b` prefix, e.g., 0b1111_0000
- Byte (only for `u8` type): with a `b` prefix, e.g., b'A'

```rust
let x: i32 = -123;
let y: u32 = 123;
println!("x is {}, y is {}", x, y);
```

#### Floating-Point Numbers

Rust provides two floating-point types: single precision `f32` and double precision `f64`. By default, floating-point numbers are of type `f64` because it offers good precision and speed.

| Type | Precision |
|:----:|:--------------------:|
| `f32`| Single precision (32-bit) |
| `f64`| Double precision (64-bit) |

```rust
let x = 2.0; // No type specified, inferred as f64 (default)
let y: f32 = 3.0; // Explicitly specified as f32
println!("x is {}, y is {}", x, y);

let x1 = 2.0; // No type specified, but will be inferred as f32 because of the next statement
let y1: f32 = 3.0; // Explicitly specified as f32
let z1 = x1 + y1;
println!("x1 is {}, y1 is {} z1 is {}", x1, y1, z1);
```

#### Booleans

```rust
let t = true;
let f: bool = false; // Explicit type annotation
println!("t is {}, f is {}", t, f);
```

#### Characters

Characters, encoded in Unicode, are 4 bytes in size in Rust:

```rust
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
println!("c is {}, z is {}, heart_eyed_cat is {}", c, z, heart_eyed_cat);
println!("The character 'c' occupies {} bytes in memory", std::mem::size_of_val(&c));
```

In Rust, the length of the `String` type depends on the encoding used. By default, Rust uses UTF-8 encoding, where each character occupies 1-4 bytes. The `char` type always occupies 4 bytes, even if some characters need only 1-3 bytes in specific encodings. The advantages are:
- Ensuring all `char` values occupy a fixed size in memory, aiding memory alignment and access efficiency.
- Avoiding the overhead of encoding conversion, directly using 4-byte values for efficient processing.
- Adequately representing all Unicode scalar values, ensuring future compatibility.

### Compound Types

Compound types can group multiple values into one type. Rust includes tuples and arrays as compound types.

#### Tuples

Tuples are a basic way to group multiple values of different types into one compound type with a fixed length.

```rust
let tup: (i32, f64, u8, char) = (-500, 6.4, 1, 'z');
let (w, x, y, z) = tup; // Destructuring the tuple
println!("The value of x is: {}", x);
```

#### Arrays

Arrays group multiple values of the same type. Unlike tuples, arrays have a fixed length.

```rust
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
println!("The first element is {}, the second element is {}", first, second);
```

## Summary

In this chapter, we covered Rust's basic data types: the four basic scalar types (integers, floating-point numbers, booleans, and characters) and the two compound types (tuples and arrays).
36 changes: 36 additions & 0 deletions Languages/en/02_BaseType/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
fn main() {
let x_immutable = 5;
println!("The value of x_immutable is: {}", x_immutable);
// x_immutable = 6; // This line will cause a compilation error because x_immutable is immutable

let mut y_mutable = 5;
println!("The value of y_mutable is: {}", y_mutable);
y_mutable = 6; // This is allowed because y_mutable is mutable
println!("The value of y_mutable is: {}", y_mutable);

let x_int_neg: i32 = -123;
let y_uint_pos: u32 = 123;
println!("x_int_neg is {}, y_uint_pos is {}", x_int_neg, y_uint_pos);

let x_float64 = 2.0; // defaults to f64
let y_float32: f32 = 3.0; // explicitly declared as f32
println!("x_float64 is {}, y_float32 is {}", x_float64, y_float32);

let t_bool = true;
let f_bool: bool = false; // explicit type declaration
println!("t_bool is {}, f_bool is {}", t_bool, f_bool);

let c_char = 'z';
let z_char = 'ℤ';
let heart_eyed_cat_char = '😻';
let z_string = String::from("string");
println!("c_char is {}, z_char is {}, heart_eyed_cat_char is {}", c_char, z_char, heart_eyed_cat_char);
println!("The character 'c_char' occupies {} bytes of memory size", std::mem::size_of_val(&c_char));
println!("The string 'z_string' content occupies {} bytes of memory size", &z_string.as_bytes().len());

let tup_var: (i32, f64, u8, char) = (-500, 6.4, 1, 'z');
let (_w_from_tup, x_from_tup, _y_from_tup, _z_from_tup) = tup_var; // Deconstruct tuple
println!("The value of x_from_tup is: {}", x_from_tup);

let a_array = [1, 2, 3, 4, 5];
let first_element = a_array[0]; let second_element = a_array[1]; println!("The first element is {}, the second element is {}", first_element, second_element); }
9 changes: 9 additions & 0 deletions Languages/en/03_CompoundType/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "compound_type"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
itertools = "0.10"
Loading