Copyright © 2022-2024 aizws.net · 网站版本: v1.2.6·内部版本: v1.23.3·
页面加载耗时 0.00 毫秒·物理内存 64.8MB ·虚拟内存 1300.0MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
我们能够使用 struct 创建自己的类型并存储复杂数据。但是有时我们需要动态、可扩展和可管理的功能。为此,Move 提供了向量 Vector。
Vector 是用于存储数据集合的内置类型。集合的数据可以是任何类型(但仅一种)。Vector 功能实际上是由 VM 提供的,不是由 Move 语言提供的,使用它的唯一方法是使用标准库和 native 函数。
script { use 0x1::Vector; fun main() { // use generics to create an emtpy vector let a = Vector::empty<&u8>(); let i = 0; // let's fill it with data while (i < 10) { Vector::push_back(&mut a, i); i = i + 1; } // now print vector length let a_len = Vector::length(&a); 0x1::Debug::print<u64>(&a_len); // then remove 2 elements from it Vector::pop_back(&mut a); Vector::pop_back(&mut a); // and print length again let a_len = Vector::length(&a); 0x1::Debug::print<u64>(&a_len); } }
Vector 最多可以存储 18446744073709551615u64(u64最大值)个非引用类型的值。要了解它如何帮助我们管理大型数据,我们试着编写一个模块。
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 } } // this method will be inaccessible for non-copyable contents public fun value<T: copy>(box: &Box<T>): T { *&box.value } public fun create<T>(): Shelf<T> { Shelf { boxes: Vector::empty<Box<T>>() } } // box value is moved to the vector public fun put<T>(shelf: &mut Shelf<T>, box: Box<T>) { Vector::push_back<Box<T>>(&mut shelf.boxes, box); } public fun remove<T>(shelf: &mut Shelf<T>): Box<T> { Vector::pop_back<Box<T>>(&mut shelf.boxes) } public fun size<T>(shelf: &Shelf<T>): u64 { Vector::length<Box<T>>(&shelf.boxes) } }
我们将创建一个 Shelf,为其提供几个 Box,并观察如何在模块中使用 vector:
script { use {{sender}}::Shelf; fun main() { // create shelf and 2 boxes of type u64 let shelf = Shelf::create<u64>(); let box_1 = Shelf::create_box<u64>(99); let box_2 = Shelf::create_box<u64>(999); // put both boxes to shelf Shelf::put(&mut shelf, box_1); Shelf::put(&mut shelf, box_2); // prints size - 2 0x1::Debug::print<u64>(&Shelf::size<u64>(&shelf)); // then take one from shelf (last one pushed) let take_back = Shelf::remove(&mut shelf); let value = Shelf::value<u64>(&take_back); // verify that the box we took back is one with 999 assert(value == 999, 1); // and print size again - 1 0x1::Debug::print<u64>(&Shelf::size<u64>(&shelf)); } }
向量非常强大,它使我们可以存储大量数据,并可以在索引的存储中使用它。
Vector 也可以表示字符串。VM支持将vector<u8>
作为参数传递给main
脚本中的函数。
也可以使用十六进制字面值(literal)在脚本或模块中定义vector<u8>
:
script { use 0x1::Vector; // this is the way to accept arguments in main fun main(name: vector<u8>) { let _ = name; // and this is how you use literals // this is a "hello world" string! let str = x"68656c6c6f20776f726c64"; // hex literal gives you vector<u8> as well Vector::length<u8>(&str); } }
更简单的方法是使用字符串字面值(literal):
script { fun main() { let _ = b"hello world"; } }
它们被视为 ASCII 字符串,也被解释为 vector。
这是标准库中 Vector 方法的简短列表:
<E>
的空向量Vector::empty<E>(): vector<E>;
Vector::length<E>(v: &vector<E>): u64;
Vector::push_back<E>(v: &mut vector<E>, e: E);
Vector::borrow()
Vector::borrow_mut<E>(v: &mut vector<E>, i: u64): &E;
Vector::pop_back<E>(v: &mut vector<E>): E;
在开始使用 Resource 之前,我们需要了解 signer 类型以及这种类型存在的原因。Signer 是一种原生的类似 Resource 的不可复制的类型,它包含了交易 ...