為自己Coding
為自己Coding

YO~~ 剛跨入AI人工智慧領域的小小工程師, 熱愛自學, 熱愛分享, 下班後的我想為自己Coding, 積極撰寫教學文, 想將自學的程式知識分享給大家, 不斷追求進步的自己, 希望有一天能回饋社會,幫助需要幫助的人, 如果您有什麼很酷的想法,也覺得我還行,歡迎您找我合作~~ IG: https://www.instagram.com/coding_4_me/

[Aptos學習筆記#7]Move進階使用 - 使用Vector管理集合 - Managing Collections with Vector

攝影師:Pixabay: https://www.pexels.com/zh-tw/photo/290470/


目錄

  1. 為什麼需要Vector?
  2. Vector是什麼?
  3. 內聯 Vector 定義的十六進制數組與字符 - Hex and Bytestring literal for inline vector definitions
  4. Vector 速查表 - Vector Cheatsheet


一. 為什麼需要Vector?

前面的筆記中我們已經很熟悉結構體的類型了,它讓我們可以創建自己的類型並儲存複雜的數據,但有時候我們需要更動態、可擴展性核可管理性的功能,這邊Move提供了向量Vector的概念來處理


二. Vector是什麼?

  • 用於儲存數據集合的內置類型( build-in type)
  • 集合數據能夠是任何類型(但僅一種)
  • Vector的功能實際上是由Move VM提供的
  • 使用Vector唯一的辦法就是使用Move標準庫和native函數


script {
    use 0x1::Vector;

    fun main() {
        // 使用泛型創建一個空的 Vector
        let a = Vector::empty<u8>();
        let i = 0;

        // 將值塞入剛剛創建的Vector中
        while (i < 10) {
            Vector::push_back(&mut a, i);
            i = i + 1;
        };

        // 現在印出Vector的長度
        let a_len = Vector::length(&a);
        0x1::Debug::print<u64>(&a_len);

        // 移除掉兩個元素
        Vector::pop_back(&mut a);
        Vector::pop_back(&mut a);

        // 再次印出Vector長度
        let a_len = Vector::length(&a);
        0x1::Debug::print<u64>(&a_len);
    }
}

Vector最多可以儲存U64個單個非引用類型(single non-reference type)的值


例子: 為了理解Vector如何幫助管理巨大的存儲量,這邊撰寫一個模塊 ( Module )

module Shelf {

    use 0x1::Vector;

    struct Box<T> {
        value: T
    }

    struct Shelf<T> {
        boxes: vector<Box<T>>
    }

    public fun create_box<T>(value: T): Box<T> {
        Box { value }
    }

    // 對於不可複製的內容本方法不可行
    public fun value<T: copy>(box: &Box<T>): T {
        *&box.value
    }

    public fun create<T>(): Shelf<T> {
        Shelf {
            boxes: Vector::empty<Box<T>>()
        }
    }

    // 將Box的值移入Vector
    public fun put<T>(shelf: &mut Shelf<T>, box: Box<T>) {
        Vector::push_back<Box<T>>(&mut shelf.boxes, box);
    }
    
    // 將Vector中的元素移出
    public fun remove<T>(shelf: &mut Shelf<T>): Box<T> {
        Vector::pop_back<Box<T>>(&mut shelf.boxes)
    }

    // 計算Vector的長度
    public fun size<T>(shelf: &Shelf<T>): u64 {
        Vector::length<Box<T>>(&shelf.boxes)
    }
}


在Script中,我們首先創建一個 Shelf,並為其提供幾個 Box,並觀察如何在Module中使用 Vector

script {
    use {{sender}}::Shelf;

    fun main() {

        // 創建一個shelf和兩個u64類型的Box
        let shelf = Shelf::create<u64>();
        let box_1 = Shelf::create_box<u64>(99);
        let box_2 = Shelf::create_box<u64>(999);

        // 將剛剛創建的兩個Box推進Vector
        Shelf::put(&mut shelf, box_1);
        Shelf::put(&mut shelf, box_2);

        // 印出長度 - 結果為2
        0x1::Debug::print<u64>(&Shelf::size<u64>(&shelf));

        // 拿走最後一個推進Vector的Box
        let take_back = Shelf::remove(&mut shelf);
        let value     = Shelf::value<u64>(&take_back);

        // 驗證我們拿出來的Box值是999
        assert(value == 999, 1);

        // 再次印出Vector長度 - 結果為1
        0x1::Debug::print<u64>(&Shelf::size<u64>(&shelf));
    }
}

Vector非常強大,它允許我們存儲大量數據(最大長度為 18,446,744,073,709,551,615),並讓我們在索引的存儲中使用它


三. 內聯 Vector 定義的十六進制數組與字符 - Hex and Bytestring literal for inline vector definitions

Vector也代表著表示字符串

VM 支援將vector<u8>當作參數傳遞給腳本中的主函數的方式


例子: 我們也可以在使用十六進制文本在Script或Module中定義一個vector<u8>

script {

    use 0x1::Vector;

    // 這是在main中傳入參數的方式
    fun main(name: vector<u8>) {
        let _ = name;

        // 這是我們使用文字的方式
        // 這邊表示的是一個hello world的字符串
        let str = x"68656c6c6f20776f726c64";

        // 十六進制的文字也傳給我們vector<u8>
        Vector::length<u8>(&str);
    }
}


有個簡單的方式就是使用字節串文字(bytestring literals)

script {

    fun main() {
        // 使用b"<我們想輸入的字符串>"的方式更簡易
        let _ = b"hello world";
    }
}

它們被當成是ASCII 字符串,也被表示為vector<u8>


四. Vector 速查表 - Vector Cheatsheet

在標準庫中的簡短Vector方法速查表

1.創建一個類型為<E>的空Vector

Vector::empty<E>(): vector<E>;

2.取得Vector長度

Vector::length<E>(v: &vector<E>): u64;

3.將元素推向Vector的末端

Vector::push_back<E>(v: &mut vector<E>, e: E);

4.獲取對Vector的可變引用,不可變引用可以使用Vector::borrow()

Vector::borrow_mut<E>(v: &mut vector<E>, i: u64): &E;

5.從Vector末端取走一個元素

Vector::pop_back<E>(v: &mut vector<E>): E;


標準庫中的Vector模塊:

move/Vector.move at main · diem/move

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…

发布评论