banner
lee

lee

Rust Learning

Rust Learning#

Basics#

  1. Variables#

    let a = 10;		// a is immutable
    let mut a = 10	// a is mutable
    

    Rust automatically releases memory when a variable goes out of scope, and Rust automatically calls drop at the closing }

  2. Basic Types#

    2.1 Numeric Types#

    Statement: A specific operation with no return value

    Expression: An expression always returns a value

    fn add_with_extra(x: i32, y: i32) -> i32 {
        let x = x + 1; // statement
        let y = y + 5; // statement
        x + y // expression
    }
    
    2.2 Character, Boolean, and Unit Types#

    String type: Dynamic string type, allocated on the heap

    let mut s = String::from("hello");
    s.push_str(", world!")	// appending a literal to the string
    

    Characters in Rust are of Unicode type, so each character occupies 4 bytes

    Strings are UTF-8 encoded, and the number of bytes occupied by characters in a string varies (1-4)

    • Append

      let mut s = String::from("Hello ")
      s.push_str("rust")
      s.push('!')
      

      push(): Appends a character

      push_str(): Appends a string

      Both methods append to the original string and do not return a new string, so the string must be mutable, marked with the mut keyword

    • Insert

      let mut s = String::from("Hello rust!")
      s.insert(5, ',')
      s.insert_str(6, " I like")
      

      String insertion operations modify the original string, so the string must be mutable, marked with the mut keyword

    • Replace

      replace

      let string_replace = String::from("I like rust")
      let new_string = string_replace.replace("rust", "Rust")
      

      replacen

      let s_replace = "I like rust learn rust"
      let ns_replacen = s_replace.replacen("rust", "Rust", 1)
      

      String replacement operations return a new string rather than modifying the original string

      replace_range: Only uses String type

      let mut s_replace_range = String::from("I like rust")
      s_replace_range.replace_range(7..8, "R")
      

      This method directly modifies the original string and does not return a new string, so it must be marked with the mut keyword

    • Delete

      pop: Deletes and returns the last character

      let mut s_pop = String::from("rust pop 中文!")
      let p1 = s_pop.pop()
      

      This method directly modifies the original string but has a return value; if the string is empty, it returns None

      remove: Deletes and returns the character at a specified position in the string

      let mut s_remove = String::from("rust remove 中文")
      string_remove.remove(0)
      

      This method directly modifies the original string but has a return value

      truncate: Deletes all characters from a specified position to the end of the string

      let mut s_truncate = String::from("测试truncate")
      s_truncate.truncate(3)
      

      This method modifies the original string and has no return value

      clear: Clears the string

      let mut s_clear = String::from("string clear")
      s_clear.clear()
      

      This method directly modifies the original string, equivalent to s_clear.truncate(0)

    • Concatenate

      Use + or += to concatenate strings, requiring the right-hand parameter to be a slice reference type

      • returns a new string, so the variable declaration does not need to be marked with the mut keyword
    2.3 Tuples#
    let x : (i32, f64, u8) = (500, 6.4, 1);
    let a = x.0;
    let b = x.1;
    
    2.4 Structs#
    1. Initialize instances, each field must be initialized
    2. The order of initializing fields does not need to match the definition
    3. When function parameters and struct fields have the same name, shorthand initialization can be used
    4. user2 differs from user1 only in email, so only the email needs to be assigned, the rest can be done with ..user1
    fn build_user(email: String, username: String) -> User {
        User {
            email,
            username,
            active: true,
            sign_in_count: 1,
        }
    }
    
    let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };
    

    Unit structs: Do not care about the content of this type, only care about its behavior

    struct AlwaysEqual;
    let subject = AlwaysEqual;
    impl SomeTrait for AlwaysEqual {}
    

    Struct output printing

    1. Manually implement Display, Debug
    2. Use derive
    #[derive(Debug)]
    struct Rectangle {
        width: u32,
        height: u32,
    }
    println!("rect1 is {:?}", rect1)
    
    2.5 Ownership and Borrowing#
    1. Every value in Rust is owned by a variable, which is called the owner of the value
    2. A value can only be owned by one variable at a time, or in other words, a value can only have one owner
    3. When the owner (variable) goes out of scope, the value will be dropped, and Rust will automatically call the drop function to clean up the variable's heap memory
    let s1 = String::from("hello");
    let s2 = s1;
    
    println!("{}, world!", s1)
    

    After s1 is assigned to s2, Rust considers s1 no longer valid, so there is no need to drop anything after s1 goes out of scope. This means ownership of s1 is transferred to s2, and s1 becomes invalid immediately after being assigned to s2. Rust prohibits the use of invalid references.

    let x = 5;
    let y = x;
    

    First, 5 is bound to variable x, then the value of x is copied to y, resulting in both x and y being equal to 5. Integers are Rust's basic data types, fixed-size simple values, so both values are assigned by automatic copying and are stored on the stack, with no need for heap memory allocation.

    2.6 References and Borrowing#

    Getting a reference to a variable is called borrowing

    • Immutable Reference

      fn main() {
          let s1 = String::from("hello");
          let len = calculate_len(&s1);
          println!("the len of '{}' is {}.", s1, len);
      }
      fn calculate_len(s: &String) -> usize {
          s.len()
      }
      
    • Mutable Reference

      fn main() {
          let mut s = String::from("hello");
          change(&mut s);
      }
      fn change(some_string: &mut String) {
          some_string.push_str(", world");
      }
      
      1. Immutable references can exist simultaneously in multiple instances
      2. Mutable references can only exist one at a time
      3. Mutable and immutable references cannot coexist
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.