Rust common collection

Common collections

Arrays and tuple s are stored on the stack. The set written here is stored on the heap, that is, the storage size is variable during operation.

Vector indefinite length array

Type signature: Vec

Provided by the standard library, multiple values can be stored, only the same type of data can be stored, and the values are stored continuously in memory.

Create Vector

When you want to create an array of indefinite length, you can use Vector.

Vec::new();
let c: Vec<i32> = Vec::new();

Create vec with initial value, use vec! Macro.
let c = vec![1, 2, 3];

Update Vector

Use push.

fn main(){
    let mut v = Vec::new();

    // After adding the element, the t rust compiler infers the type, and there is no need to display the specified type.
    v.push(1)
}

Delete Vector

Like other struct s, when the Vector leaves the scope, it is cleaned up, and all elements are cleaned up.

Read the value in the Vector

Index and get methods.

fn main(){
    let mut v = vec![1, 2, 3, 4, 5];
    let one: &i32 = &v[0];

    match v.get(0) {
        Some(one) => one,
        None => print!(),
    }
}

If the index is exceeded by subscript, t rust will panic, and match will match None.

Ownership and borrowing rules.

You cannot have both mutable and immutable references within the same scope.

fn main(){
    let mut v = vec![1, 2, 3, 4, 5];
    let one = &mut v[0];
    // T rust will report an error here because it cannot borrow v for multiple times. Both v and one are variable now, so an error is reported.
    v.push(1);

    print!("{}\n", one)
}

fn main(){
    let mut v = vec![1, 2, 3, 4, 5];
    let one = &v[0];
    // T rust will report an error here because it cannot be both variable and constant.
    v.push(1);

    print!("{}\n", one)
}

The borrowing rule prevents the reference from pointing to the original address after the memory address of a data on the heap changes. There will be mistakes.

Traverse the values inside

for i in &c {}

Vector + enum

Because the types required in the Vector are the same. Therefore, you can use enumeration to define parameters in enumeration to receive different types, so as to put different types of data in Vector.

enum Money {
    CNY,
    JPY(u16),
    USD(Bank),
}

#[derive(Debug)]
enum Bank {
    HSBC,
    BOC,
}

fn main() {
    let gotoCountry = vec![
        Money::CNY,
        Money::JPY(1000),
        Money::USD(Bank::HSBC),
    ];
}

String

String uses utf-8 by default.

At the core language level, t rust has only one string type: String slice str (& STR).

String slicing

Reference to strings stored elsewhere and compiled by UTF-8. String literals are stored in binary files and are also string slices.

String type and & STR are two things.

String type

From the standard library, not the core language. Is a more advanced type.

Create a new string

String::new();
let mut s = String::new();
The new() method cannot initialize the value directly.

to_string();
let s = "hello".to_String();

String::from();
let s = String::from("hello.");

Update String

push_str(); Append a String slice to a String.

let mut s = String::from("hello.");
s.push("World");

push(); Append a single character to a String.

  • Splicing requires String type in front and String reference in the back.
    let s = s1 + &s2
    After splicing, s1 cannot be used.

format!();
format("{}{}{}", a, b, c)
Similar to python. But will not take ownership.

String index

The t rust string does not support index syntax access.

len();
let s = String::from("dd").len();

Because the bottom layer of String is an indefinite length list of vec, which contains unicode byte values, this method is eliminated.

In addition, the complexity of the operation is O(1). String cannot guarantee the length, so you need to traverse all the contents.

Byte, scalar value and font cluster

bytes, chars, scalar value

Cut String

let s = &hello[0..4];

Must be cut along the boundary of the character.

HashMap

hashmap < K, V > key value pairs, similar to dictionaries. Data exists on the heap, hashmap is isomorphic, all keys are of one type, and all values are of one type.

Create hashmap

Create an empty HashMap: new();

Add data: insert();

let mut account: HashMap<String, u16> = HashMap::new();

let mut account = HashMap::new();
account.insert(String::from("achu"), 123);

You need to manually import use std::collections::HashMap;

collect
A hashmap can be built by using the collect method on a Vector whose element type is tuple. The essence is Vector.

The collect method can integrate data into many collection types, including hashMap.

Merge two VECs into hashmap

let teams = vec!["blue".to_string(), "red".to_string()];
let scores = vec![10, 50];
let res: HashMap<_, _> = teams.iter().zip(scores.iter()).collect();
println!("res = {:#?}", res); 

Traversing hashMap

Recommendation: use for (I, K) in & HashMap {}

The. get() method is used in conjunction with match to match the returned option enumeration.

HashMap ownership

  • For types that implement copy trait (eg: i32), the value is assigned to hashmap.
  • For the value with ownership, the value will be moved and the ownership will be transferred to hashmap. If the value is inserted into hashmap, the value itself will not be moved.
use std::collections::HashMap;
fn main() {
    let username = String::from("achu");
    let password = String::from("1234");

    let mut account = HashMap::new();

    // At this point, ownership of the two variables is transferred to hashmap
    account.insert(username, password);

    // If you call here again, an error will be reported
    println!("{}{}", username, password)
}

Update hashmap

hashmap size is variable, and each k can only correspond to one v.

replace

Insert the same key and different value s will be replaced.

There is no key to insert again

entry(k);, Return enumeration to query whether the key exists.

or_insert(5), the key exists and returns to a variable reference of the corresponding V. If the key does not exist, insert the method parameter as a new value of k and return a variable reference to this value.

use std::collections::HashMap;
fn main() {
    let text = "hello world";
    let mut map = HashMap::new();

    for i in text.split_ascii_whitespace() {
        // Here is the value passed to hashmap. If there is a value, it will return the reference of this value. If there is no value, it will be set to 0, and then return the reference of value
        let count = map.entry(i).or_insert(0);

        // Here we need to dereference
        *count += 1;
    }

    print!("{:#?}", map)
}

Keywords: Rust

Added by daggardan on Mon, 29 Nov 2021 15:11:21 +0200