Move Resource 读取和修改
Move 有两个内建函数用来读取和修改 Resource。它们的功能就像名字一样:borrow_global 和 borrow_global_mut。
不可变借用 borrow_global
在所有权和引用一章,我们已经了解了可变引用(&mut)和不可变的引用(&)。现在是时候实践这些知识了!
// modules/Collection.move module Collection { // added a dependency here! use 0x1::Signer; use 0x1::Vector; struct Item has store, drop {} struct Collection has key, store { items: vector<Item> } // ... skipped ... /// get collection size /// mind keyword acquires! public fun size(account: &signer): u64 acquires Collection { let owner = Signer::address_of(account); let collection = borrow_global<Collection>(owner); Vector::length(&collection.items) } }
这里发生了很多事情。首先,让我们看一下函数的签名。全局函数 borrow_global 返回了对 Resource T 的不可变引用。其签名如下:
native fun borrow_global<T: key>(addr: address): &T;
通过使用此功能,我们可以读取存储在特定地址的 Resource。这意味着该模块(如果实现了此功能)具有读取任何地址上任何 Resource 的能力,当然这里的 Resource 指的是该模块内定义的任何 Resource。
另一个结论:由于 Borrow
检查,你不能返回对 Resource 的引用或对其内容的引用(因为对 Resource 的引用将在函数作用域结束时消失)。
由于 Resource 是不可复制的类型,因此不能在其上使用取值运算符 “*”。
Acquires 关键字
还有另一个值得解释的细节:关键字 acquires
。该关键字放在函数返回值之后,用来显式定义此函数获取的所有 Resource。我们必须指定所有获取的 Resource,即使它实际上是子函数所获取的 Resource,即父函数必须在其获取列表中包含子函数的获取列表。
acquires 使用方法如下:
fun <name>(<args...>): <ret_type> acquires T, T1 ... {
可变借用 borrow_global_mut
要获得对 Resource 的可变引用,请添加 _mut
到 borrow_global
后,仅此而已。让我们添加一个函数,将新的 Item 添加到集合中。
module Collection { // ... skipped ... public fun add_item(account: &signer) acquires T { let collection = borrow_global_mut<T>(Signer::address_of(account)); Vector::push_back(&mut collection.items, Item {}); } }
对 Resource 的可变引用允许创建对其内容的可变引用。这就是为什么我们可以在此示例中修改内部向量 items 的原因。
native fun borrow_global_mut<T: key>(addr: address): &mut T;
函数 move_from 用来将 Resource 从账户下取出。我们将实现 destroy 函数,将 Collection 的 T Resource ...