I. What is Rust

Rust is a general-purpose, compiled programming language developed under the leadership of Mozilla. The design guidelines are “safe, concurrent, and practical”, and support functional, concurrent, procedural, and object-oriented programming styles. – Wikipedia

II. Language characteristics

  1. Language features

    Rust is much closer in deep syntax to languages in the meta-language family like Haskell. Basically, every part of a function body is an expression, even a control flow operator.

  2. Memory safety

    Null pointers, dangling pointers and data contention are not allowed in safe code. Values can only be initialized with a series of fixed forms, requiring all inputs to have been initialized.

  3. Memory management

    Does not use automatic garbage collection system, through RAII to manage memory and resources, but also optional reference counting.

  4. Ownership

    All values have a unique owner, and the valid range of values is the same as the valid range of the owner.

  5. Type Polymorphism

    Rust’s type system supports a type class-like mechanism called “traits”, which was inspired by Haskell. This is a facility for specific homogeneous methods, achieved by adding constraints to type variable declarations. Other features from Haskell, such as higher type polymorphism, are not yet supported.

III. Data Types

Rust has the following types in total: integer, floating point, boolean, character, and composite.

  1. Integer types (i, u)

    The Rust language is similar to the C family of languages in that shaped data is divided into signed and unsigned types based on whether it is signed or unsigned.

    Number of Bits signed Unsigned
    8-bit i8 u8
    16-bit i16 u16
    32-bit i32 u32
    64-bit i64 u64
    128-bit i128 u128

    The default type of integer is i32. (i, u means int, uint).

    1
    2
    
    let a = 10; // i32
    let b: i64 = 20; // i64
    
  2. Floating-point (f)

    Rust supports 32-bit floating point (f32) and 64-bit floating point (f64), just like any other language. By default, the floating-point data type is 64-bit floating-point, because modern computer processors compute both types of floating-point numbers at almost the same speed, but with higher precision for 64-bit floating-point numbers.

    1
    2
    
    let a = 10.0; // f64
    let b: f32 = 20.0; // f32
    
  3. Boolean (bool)

    Like js, the value is true or false.

  4. Character type (char)

    Character type is 4 bytes in size, representing Unicode scalar value.

    Note: Since there are two kinds of Chinese character encoding (GBK and UTF-8), the use of Chinese strings in programming may lead to garbled code, which is due to the inconsistency between the source program and the command line text encoding, so both strings and characters in Rust must use UTF-8 encoding, otherwise the compiler throws an exception.

    1
    
    let c = 'a';
    
  5. composite type

    Arrays are familiar to everyone, and are a set of data of the same type included by the brackets, but we need to know that arrays in Rust are fixed length, which means we can’t add or delete an array after we determine it.

    1
    2
    3
    4
    5
    
    let arr = [1, 2, 3, 4, 5];
    let arr2: [i32; 5] = [1, 2, 3, 4, 5]; // An i32 array of length 5
    let arr3 = [1; 3]; // equal to [1, 1, 1]
    
    let one = arr[0]; // 1
    

    Rust also has a tuple type, which can contain different data types.

    1
    
    let tup: (i32, f32, char) = (10, 20.0, 'a');
    

IV. Structs

Structs are a bit like interfaces in typescript.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
struct Person {
    name: String,
    sex: String,
    age: u32
}

let p1 = Person {
    name: String::from("abc"),
    sex: String::from("male"),
    age:18
}

// Structure update syntax, similar to the deconstruction of js
let p2 = Person{
    name: String::from("123"),
    ..p1
}

V. Enumeration classes

1
2
3
enum Phone {
    IPhone, Huawei
}

Enumerated classes are often used with match syntax to implement branching structures, similar to switch in other syntaxes, but switch is not supported in Rust.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
fn main() {
enum Phone {
    IPhone(u32),
    Huawei {url: String},
}
let phone = Phone::IPhone(123);
let phone2 = Phone::Huawei {url: String::from("hahaha")};

match phone {
    Phone::IPhone(i) => {
        println!("{}", i);
    },
    Phone::Huawei { url } => {
        println!("{}", url);
    }
}

match phone2 {
    Phone::IPhone(i) => {
        println!("{}", i);
    },
    Phone::Huawei { url } => {
        println!("{}", url);
    }
}
}

// 123
// hahaha

In addition to being able to branch on enumerated classes, match can branch on data of integer, floating point, character, and string slice-and-reference (&str) types.

Exceptions to branching on non-enumeric classes must be handled and are indicated by an underscore _.

VI. Ownership

Ownership is a syntactic mechanism designed by the Rust language for efficient use of memory

The concept of ownership is a concept created to allow Rust to more efficiently analyze the usefulness of memory resources for memory management during the compilation phase.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Move
// The first variable cannot be accessed in this case
let s1 = String::from("hello");
let s2 = s1; 
println!("{}, world!", s1); // Error! s1 is no longer available


// Cloning
// This can be
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);