Aptos

2025年09月10日更新 4 人订阅
原价: ¥ 2.2 限时优惠
专栏简介 Aptos 开发实战:从环境搭建到第一个 Hello World Aptos 开发指南:在 JetBrains 编辑器中配置运行、编译、测试与发布部署,实现更高效开发 Aptos 区块链智能合约入门:使用 Move 实现消息存储与检索 Aptos Move 语言中的变量管理与内存所有权机制详解 Aptos Move 编程语言中的四大基础类型解析:UINT、STRING、BOOL 与 ADDRESS 深入解读 APTOS-MOVE 中的 Vector 向量核心特性与操作 深入理解APTOS-MOVE中的函数修饰符:核心概念与应用 深入解读 Aptos Move 的 Struct 特性与四大能力 Aptos Move 控制流解析:IF、WHILE与LOOP的深入解读 Aptos Move 模块的特性与实操指南:模块引用与作用域管理 Aptos Move 模块的发布与交互:完整指南 深入理解 Aptos Move 中的 Object 创建与管理 深入探索 Aptos Move:Object 配置与实操指南 使用 Aptos Move 实现随机数生成:从 AIP-41 到实战操作 Aptos Move 实践指南:构建并部署同质化代币水龙头 (FA Faucet) Aptos Move NFT 项目实操指南:从开发到部署全流程解析 Aptos Move 开发入门:从环境搭建到合约部署全流程实录 Aptos Move 入门:从零到一的合约开发与测试实战 Move 语言核心:布尔逻辑与地址类型的实战精解 深入 Aptos Move:从public到friend,函数可见性详解 Aptos Move 编程:for、while 与 loop 循环的实战详解 Aptos Move 安全编程:abort 与 assert! 错误处理实战 Aptos Move 实战:基础运算与比较逻辑的实现与测试 Aptos Move 性能优化:位运算与移位操作实战 Aptos Move 实战:as 关键字与整数类型转换技巧 Aptos Move DeFi 实战:从零构建流动性池兑换逻辑 Aptos Move 实战:用 signer 实现合约所有权与访问控制 Aptos Move 核心安全:& 与 &mut 引用机制详解 Aptos Move 实战:全面掌握 SimpleMap 的增删改查 Aptos Move 入门:掌握链上资源(Resource)的增删改查 Aptos Move 深度实践:用嵌套数据结构构建链上金银储备系统 Aptos Move 实操:如何用 Tables 构建一个链上房产管理系统 Aptos Move 实操:如何用 Tables 构建一个链上房产管理系统 Aptos Move实战:5分钟掌握链上向量(Vector)核心操作

Aptos Move实战:5分钟掌握链上向量(Vector)核心操作

AptosMove实战:5分钟掌握链上向量(Vector)核心操作想快速开发Aptos上的智能合约?首先你必须掌握Move语言的核心数据结构。向量(Vector)作为最基础且常用的动态数组,其概念类似于其他编程语言中的数组(Array)或列表(List),其操作的熟练度直接

Aptos Move实战:5分钟掌握链上向量(Vector)核心操作

想快速开发 Aptos 上的智能合约?首先你必须掌握 Move 语言的核心数据结构。向量(Vector)作为最基础且常用的动态数组,其概念类似于其他编程语言中的 数组(Array)列表(List),其操作的熟练度直接影响你的开发效率。本文将通过一个高度精炼的 Move 代码示例,带你用最少的时间,最快地掌握向量的创建、增、删、改、查等所有关键操作。准备好了吗?让我们立即进入实战!

实操

Aptos Move Vectors

示例一

module net2dev_addr::vectors_one {
    use std::vector;

    fun vector_basics(): vector<u64> {
        // Initialize a Vector
        let list = vector::empty<u64>();

        // insert 10 at the end of the vector (last index);
        list.push_back(10); // [10]
        list.push_back(20); // [10, 20]

        // store 30 at specified index 2
        list.insert(2, 30); // [10, 20, 30]
        list.insert(3, 50); // [10, 20, 30, 50]
        list.insert(2, 20); // [10, 20, 20, 30, 50]

        // swap index 0 with 1
        list.swap(0, 1); // [20, 10, 20, 30, 50]

        // return vector index 2 mutable reference value
        let value = list.borrow_mut(2); // 20
        *value += 10; // 30
        list.insert(2, *value); // [20, 10, 30, 20, 30, 50]

        // remove element from vector at index 3
        list.remove(3); // [20, 10, 30, 30, 50]

        // return last element from vector (last index) and remove it
        list.pop_back(); // [20, 10, 30, 30] returns 50
        list // [20, 10, 30, 30]
    }

    #[test_only]
    use std::debug::print as p;

    #[test]
    fun test_function() {
        let list = vector_basics();
        assert!(list.length() == 4, 1);
        p(&list);
    }
}

这段 Aptos Move 代码通过一个名为 vector_basics 的函数,生动地展示了 vector(动态数组)的核心操作方法。首先,它使用 vector::empty<u64>() 创建了一个空的 u64 类型向量。接着,代码演示了如何添加元素:push_back 用于在末尾追加,insert 则可以在指定索引位置插入。此外,它还展示了如何使用 swap 交换两个元素的位置。在修改数据方面,代码通过 borrow_mut 获取了特定位置元素的可变引用,并直接更新了其值。对于删除操作,remove 可以删除指定索引的元素,而 pop_back 则会移除并返回向量的最后一个元素。最后,代码还包含一个 test_function 测试函数,它调用 vector_basics 并使用 assert! 来验证最终向量的长度是否符合预期,确保了代码逻辑的正确性。这串代码是学习 Move 语言中 vector 用法的绝佳实例。

测试

➜ aptos move test
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING my-dapp
Running Move unit tests
[debug] [ 20, 10, 30, 30 ]
[ PASS    ] 0x48daaa7d16f1a59929ece03157b8f3e4625bc0a201988ac6fea9b38f50db5ef3::vectors_one::test_function
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
  "Result": "Success"
}

这段终端输出是执行 aptos move test 命令后的成功反馈。它首先加载了项目依赖库并完成了编译,然后进入单元测试环节。其中,[debug] [ 20, 10, 30, 30 ] 这一行是关键,它正是我们代码中测试函数打印出的最终向量状态,直观地验证了前面一系列增、删、改、换操作的最终结果。随后的 [ PASS ] 状态和 Test result: OK. Total tests: 1; passed: 1; failed: 0 的总结,明确地告诉我们,vectors_one::test_function 这个测试用例已经顺利通过了所有断言检查,证明我们的代码逻辑完全符合预期,整个测试过程圆满成功。

示例二

module net2dev_addr::vectors_one {
    use std::vector;
    use std::debug::print as p;

    fun vector_basics(): vector<u64> {
        // Initialize a Vector
        let list = vector::empty<u64>();

        // insert 10 at the end of the vector (last index);
        list.push_back(10); // [10]
        list.push_back(20); // [10, 20]

        // store 30 at specified index 2
        list.insert(2, 30); // [10, 20, 30]
        list.insert(3, 50); // [10, 20, 30, 50]
        list.insert(2, 20); // [10, 20, 20, 30, 50]

        // swap index 0 with 1
        list.swap(0, 1); // [20, 10, 20, 30, 50]

        // return vector index 2 mutable reference value
        let value = list.borrow_mut(2); // 20
        *value += 10; // 30
        list.insert(2, *value); // [20, 10, 30, 20, 30, 50]

        // remove element from vector at index 3
        list.remove(3); // [20, 10, 30, 30, 50]

        // return last element from vector (last index) and remove it
        list.pop_back(); // [20, 10, 30, 30] returns 50
        list // [20, 10, 30, 30]
    }

    // 打印向量中的所有元素,同时保持向量内容不变。它相当于一个调试工具,用于查看向量中存储的所有值。
    fun while_loop_vector(list: vector<u64>): vector<u64> {
        // return vector length
        let length = list.length();
        let i: u64 = 0;
        while (i < length) {
            let value = list.borrow(i);
            p(value);
            i += 1;
        };
        list
    }

    #[test]
    fun test_function() {
        let list = vector_basics();
        assert!(list.length() == 4, 1);
        assert!(list == vector[20, 10, 30, 30], 2);
        assert!(list.contains(&10), 3); // return true if vector contains 10;
        assert!(list.contains(&30), 3);
        let (b, index) = list.index_of(&30); // returns true and the index of a value
        assert!(b, 4);
        assert!(index == 2, 5);

        p(&list);

        let list = while_loop_vector(list);
        assert!(list == vector[20, 10, 30, 30], 6);
        assert!(list.length() == 4, 7);
        p(&list);
    }
}

这段Aptos Move代码定义了一个名为vectors_one的模块,主要演示了向量(vector)的基本操作。该模块包含三个函数:vector_basicswhile_loop_vector 和一个测试函数 test_function

vector_basics函数创建并操作一个u64类型的向量,展示了向量的初始化、添加(push_backinsert)、交换(swap)、可变引用(borrow_mut)、删除(removepop_back)等多种方法,最终返回一个被修改后的向量。

while_loop_vector函数则演示了如何使用while循环遍历向量中的所有元素,并使用borrow方法获取每个元素的值,通过p(value)进行打印,这是一种调试和检查向量内容的方法。

最后,test_function是一个测试用例,它调用前两个函数,并使用assert!宏来验证向量在执行各种操作后是否符合预期状态。它检查了向量的长度、内容、是否包含特定元素(contains)以及某个元素的索引(index_of),确保了向量操作的正确性。

测试

➜ aptos move test
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING my-dapp
Running Move unit tests
[debug] [ 20, 10, 30, 30 ]
[debug] 20
[debug] 10
[debug] 30
[debug] 30
[debug] [ 20, 10, 30, 30 ]
[ PASS    ] 0x48daaa7d16f1a59929ece03157b8f3e4625bc0a201988ac6fea9b38f50db5ef3::vectors_one::test_function
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
  "Result": "Success"
}

这段测试结果显示,你运行了Move语言的单元测试,并且测试成功通过

[debug]开头的几行是代码中p(&list)p(value)等调试打印语句的输出,展示了向量在不同操作步骤后的实际内容。这有助于开发者在测试过程中观察数据变化。

[ PASS ]这一行则明确告诉你,名为test_function的测试函数成功执行,并且所有assert!断言都通过了。

最后,Test result: OK. Total tests: 1; passed: 1; failed: 0 总结了测试的整体情况:总共运行了1个测试,1个通过,0个失败,表明你的代码在逻辑上是符合预期的。

示例三

module net2dev_addr::vectors_one {
    use std::vector;
    use std::string::utf8;
    use std::debug::print as p;

    fun vector_basics(): vector<u64> {
        // Initialize a Vector
        let list = vector::empty<u64>();

        // insert 10 at the end of the vector (last index);
        list.push_back(10); // [10]
        list.push_back(20); // [10, 20]

        // store 30 at specified index 2
        list.insert(2, 30); // [10, 20, 30]
        list.insert(3, 50); // [10, 20, 30, 50]
        list.insert(2, 20); // [10, 20, 20, 30, 50]

        // swap index 0 with 1
        list.swap(0, 1); // [20, 10, 20, 30, 50]

        // return vector index 2 mutable reference value
        let value = list.borrow_mut(2); // 20
        *value += 10; // 30
        list.insert(2, *value); // [20, 10, 30, 20, 30, 50]

        // remove element from vector at index 3
        list.remove(3); // [20, 10, 30, 30, 50]

        // return last element from vector (last index) and remove it
        list.pop_back(); // [20, 10, 30, 30] returns 50
        list // [20, 10, 30, 30]
    }

    // 打印向量中的所有元素,同时保持向量内容不变。它相当于一个调试工具,用于查看向量中存储的所有值。
    fun while_loop_vector(list: vector<u64>): vector<u64> {
        // return vector length
        let length = list.length();
        let i: u64 = 0;
        while (i < length) {
            let value = list.borrow(i);
            p(value);
            i += 1;
        };
        list
    }

    fun read_element(element: u64) {
        p(&element);
    }

    fun update_element(element: &u64) {
        let value = *element + 1;
        p(&value);
    }

    fun for_each_vector(list: vector<u64>) {
        p(&utf8(b"For Each"));

        list.for_each(|element| {
            read_element(element);
        });

        p(&utf8(b"For Each Mutable"));
        list.for_each_mut(|element| {
            update_element(element);
        });
    }

    #[test]
    fun test_function() {
        let list = vector_basics();
        assert!(list.length() == 4, 1);
        assert!(list == vector[20, 10, 30, 30], 2);
        assert!(list.contains(&10), 3); // return true if vector contains 10;
        assert!(list.contains(&30), 3);
        let (b, index) = list.index_of(&30); // returns true and the index of a value
        assert!(b, 4);
        assert!(index == 2, 5);

        p(&list);

        p(&utf8(b"While Loop"));
        let list = while_loop_vector(list);
        assert!(list == vector[20, 10, 30, 30], 6);
        assert!(list.length() == 4, 7);
        p(&list);

        for_each_vector(list);
    }
}

这段 Aptos Move 代码是一个名为 vectors_one 的模块,它全面演示了 Aptos 中向量(vector)的多种常用操作。代码中定义了三个核心函数来展示不同的操作方式:

  • vector_basics:这个函数是入门级的向量操作指南。它从创建一个空向量开始,逐步展示了如何向向量尾部添加元素push_back)、在指定位置插入元素insert)、交换元素位置swap)、修改指定位置的元素borrow_mut)以及删除元素removepop_back),最后返回修改后的向量。
  • while_loop_vector:该函数演示了如何使用传统的 while 循环来遍历向量。它获取向量的长度,然后通过一个计数器迭代访问每一个元素,并使用 borrow 方法获取元素的值进行打印,这是一种常见的调试手段。
  • for_each_vector:这个函数则展示了 Move 语言中更现代、更简洁的迭代方式:for_eachfor_each_mut。前者用于只读遍历,后者则允许在遍历时修改向量中的元素。它通过调用 read_elementupdate_element 这两个辅助函数,清晰地展示了两种迭代方式的不同应用场景。

最后,test_function 包含了多个断言(assert!),用于验证以上所有操作的正确性,确保向量在经过一系列增删改查后,其内容和状态都符合预期,充分保障了代码的可靠性。

测试

➜ aptos move test
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING my-dapp
Running Move unit tests
[debug] [ 20, 10, 30, 30 ]
[debug] "While Loop"
[debug] 20
[debug] 10
[debug] 30
[debug] 30
[debug] [ 20, 10, 30, 30 ]
[debug] "For Each"
[debug] 20
[debug] 10
[debug] 30
[debug] 30
[debug] "For Each Mutable"
[debug] 21
[debug] 11
[debug] 31
[debug] 31
[ PASS    ] 0x48daaa7d16f1a59929ece03157b8f3e4625bc0a201988ac6fea9b38f50db5ef3::vectors_one::test_function
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
  "Result": "Success"
}

这段测试结果表明,你的Move代码中的所有单元测试都成功通过了。[debug]开头的多行输出是你在代码中设置的调试信息,它们清晰地展示了向量在不同操作(while 循环、for_eachfor_each_mut)过程中,元素的具体值变化。这验证了向量的遍历和修改功能按预期工作,例如在 for_each_mut 遍历中,每个元素的值都成功地增加了 1。最终的摘要 Test result: OK. Total tests: 1; passed: 1; failed: 0 确认了测试的整体结果:总共运行了 1 个测试,所有测试都成功通过,没有失败。

总结

通过本文的实战演练,你已经全面掌握了 Aptos Move 语言中向量的各种核心操作。我们从基础的增删改查,到更高级的引用和遍历,每一个步骤都通过清晰的代码和成功的测试结果进行了验证。这篇指南旨在帮你快速上手,避免陷入冗长的理论学习。熟练运用这些向量操作,将让你在未来的 Aptos 链上应用开发中事半功倍。

参考

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论