blog.dopana

Back

Bài thứ chín trong loạt Rust cơ bản. Khác với mảng và tuple cố định kích thước từ lúc biên dịch, collection trỏ đến dữ liệu cấp phát trên heap và có thể mở rộng hoặc thu nhỏ linh hoạt trong khi chạy.

graph TD
    subgraph Collections["Rust Standard Collections"]
        Vec["Vec&lt;T&gt;<br/>Dynamically sized ordered list"]
        String["String<br/>UTF-8 encoded bytes wrapper"]
        HashMap["HashMap&lt;K, V&gt;<br/>Key-Value lookup table"]
    end

    subgraph Memory["Memory Layout"]
        Stack["Stack: Pointer + Capacity + Length"]
        Heap["Heap: Dynamic buffer allocation"]
    end

    Vec --> Stack
    String --> Stack
    HashMap --> Stack
    Stack -->|points to| Heap

Vector (Vec<T>)#

Vector lưu trữ nhiều giá trị cùng kiểu dữ liệu liên tiếp nhau trong bộ nhớ:

graph LR
    subgraph StackMem["Stack Memory"]
        V["vec"]
        V_ptr["ptr"]
        V_cap["cap: 4"]
        V_len["len: 3"]
    end

    subgraph HeapMem["Heap Memory"]
        H0["[0]: 10"]
        H1["[1]: 20"]
        H2["[2]: 30"]
        H3["[3]: Unallocated"]
    end

    V_ptr --> H0
    H0 --- H1 --- H2 --- H3

Chuỗi UTF-8 (String)#

Trong Rust, String là một wrapper bọc quanh Vec<u8> được đảm bảo là văn bản UTF-8 hợp lệ:

graph LR
    subgraph StackFrame["Stack Frame"]
        S["s (String)"]
        S_ptr["ptr"]
        S_cap["cap: 7"]
        S_len["len: 7"]
    end

    subgraph HeapBuffer["Heap Buffer"]
        B0["'f' (102)"]
        B1["'o' (111)"]
        B2["'o' (111)"]
        B3["'b' (98)"]
        B4["'a' (97)"]
        B5["'r' (114)"]
        B6["'!' (33)"]
    end

    S_ptr --> B0
    B0 --- B1 --- B2 --- B3 --- B4 --- B5 --- B6
let mut s = String::from("foo");
s.push_str("bar");
s.push('!');

// Nối chuỗi với + hoặc format!
let s1 = String::from("Xin chào, ");
let s2 = String::from("Rust!");
let s3 = format!("{s1}{s2}"); // format! không lấy quyền sở hữu của s1, s2
rust

Do ký tự UTF-8 có độ dài byte thay đổi (từ 1 đến 4 byte), Rust không hỗ trợ truy cập chỉ số trực tiếp như s[0] để tránh trả về byte ký tự không hợp lệ. Thay vào đó, hãy dùng string slice &s[0..4] hoặc duyệt qua .chars().

Hash Map (HashMap<K, V>)#

Hash map ánh xạ các khóa (key) kiểu K tới các giá trị (value) kiểu V thông qua hàm băm (hashing):

graph LR
    subgraph HashFunc["Hash Function"]
        K1["Key: 'Blue'"] --> H1["Hash('Blue')"]
        K2["Key: 'Yellow'"] --> H2["Hash('Yellow')"]
    end

    subgraph BucketArray["Bucket Array on Heap"]
        H1 --> B1["Bucket 2: ('Blue', 10)"]
        H2 --> B2["Bucket 5: ('Yellow', 50)"]
    end

Kết luận#

Vector lưu trữ danh sách phần tử có thứ tự, String quản lý văn bản UTF-8 cấp phát trên heap an toàn, và HashMap quản lý liên kết cặp key-value. Bài tiếp theo trong loạt: xử lý lỗi.

Tài liệu tham khảo#