iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Web 3

Smart-Contract Language: Move系列 第 15

Day 15 Advanced Topics: Vector

  • 分享至 

  • xImage
  •  

前幾篇我們介紹了透過 Struct 可以創建自己的類型和儲存複雜數據的類型,但有時候開發上會需要更具擴展性和可管理性的東西,也就是今天要介紹的向量 (Vector)

Vector 是用於存儲數據集合的內置類型。它是任何類型(但只能一種)集合的通用解決方案。因為它的功能是由虛擬機提供給的;使用它的唯一方法是使用 Move 標準庫native函數。

schema

  • vector[]
    • 宣告空的 vector
  • vector[e1, …, en]
    • 宣告 n 個元素的 vector

通常,vector 可以自動推斷類型,如果無法推斷則可以使用之前所提到的,顯示指定類型。

vector<T>[]: vector<T>
vecctor<T>[e1, ..., en]: vector<T>

example

(vector[]: vector<bool>);
(vector[0u8, 1u8, 2u8]: vector<u8>);
(vector<u128>[]: vector<u128>);
(vector<address>[@0x42, @0x100]: vector<address>);

vector 文字

Move 中向量的一個常見用例是 “byte arrays” vector<u8> 這些值通常用於加密目的,例如公鑰或hash 結果。這些值非常常見,以至於提供了特定的語法以使值更具可讀性,而不必使用以數字形式指定vector[] ,目前可以資源兩種 type: byte srings 和 hex strings (十六進制)。

Byte strings

字節字符串是以 b 為前綴的帶引號的字符串文字,例如b"Hello!\n"

這些是允許轉義序列的 ASCII 編碼字符串。目前,支持的轉義序列是

  • \n
    • 換行
  • \r
    • 回車
  • \t
    • 標籤
  • \
    • 反斜杠
  • \0
    • 無效的
  • \”
    • 引用
  • \xHH
    • 十六進制轉義,插入十六進製字節序列

十六進制字符串

十六進製字符串是以 x 為前綴的帶引號的字符串文字,例如x"48656C6C6F210A"

每個字節對,範圍從00FF,都被解釋為十六進制編碼u8值。所以每個字節對對應於結果中的一個條目vector<u8>

script {
fun byte_and_hex_strings() {
    assert!(b"" == x"", 0);
    assert!(b"Hello!\n" == x"48656C6C6F210A", 1);
    assert!(b"\x48\x65\x6C\x6C\x6F\x21\x0A" == x"48656C6C6F210A", 2);
    assert!(
        b"\"Hello\tworld!\"\n \r \\Null=\0" ==
            x"2248656C6C6F09776F726C6421220A200D205C4E756C6C3D00",
        3
    );
}
}

操作

vectorStd::Vector通過 Move 標準庫中的模塊支持以下操作:

  • Vector::empty(): vector
    • 創建一個可以存儲類型值的空向量
  • Vector::singleton(t: T): vector
    • 創建一個大小為 1 的向量,其中包含 t
  • Vector::push_back(v: &mut T, t: T)
    • 添加 t 到末尾 v
  • Vector::pop_back(v: &mut T): T
    • 刪除並返回最後一個元素 t
  • Vector::borrow(v: &vector, i: u64): &T
    • 返回 T 位於特定索引的不可變引用
  • Vector::borrow_mut(v: &mut vector, i: u64): &mut T
    • 返回 T 位於特定索引的可變引用
  • Vector::destroy_empty(v: vector)
    • 刪除 v
  • Vector::append(v1: &mut vector, v2: vector)
    • 將元素 v2 添加到 v1 的後面

example

use Std::Vector;

let v = Vector::empty<u64>();
Vector::push_back(&mut v, 5);
Vector::push_back(&mut v, 6);

assert!(*Vector::borrow(&v, 0) == 5, 42);
assert!(*Vector::borrow(&v, 1) == 6, 42);
assert!(Vector::pop_back(&mut v) == 6, 42);
assert!(Vector::pop_back(&mut v) == 5, 42);

銷毀和複製 vectors

vector 的能力一樣受到元素類型能力影響,如果使用包含沒有元素的向量,需要而外設定顯式銷毀 Vector::destroy_empty 或是給予 drop 能力。

需要注意是,如果使用顯式銷毀,但元素數量不等於 0,將會在運行時終止。

fun destroy_any_vector<T>(vec: vector<T>) {
	
    Vector::destroy_empty(vec) // deleting this line will cause a compiler error
}

fun destroy_droppable_vector<T: drop>(vec: vector<T>) {
    // valid!
}

同樣,除非元素類型具有 copy 能力,否則也無法複製向量 ,複製大型的向量將會耗費巨大費用,因此需要特別注意使用。

讓我們 Move to Day 16

相關資料

Move 標準庫: https://github.com/diem/move/tree/main/language/move-stdlib/sources


上一篇
Day 14 Advanced Topics: Generics
下一篇
Day 16 Advanced Topics: Signer
系列文
Smart-Contract Language: Move30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言