2.1 基本数据类型 (Primitives)
无符号整型家族:u8/u64/u128/u256
Move提供了四种无符号整数类型,用于表示正整数:
类型范围:
u8: 0 到 255 (2^8 - 1)u64: 0 到 18,446,744,073,709,551,615 (2^64 - 1)u128: 0 到 2^128 - 1 (约3.4e38)u256: 0 到 2^256 - 1 (约1.16e77)
u8:适用于小的计数器、状态标志(如年龄、选项枚举)u64:最常用!适用于代币余额、时间戳、大多数业务逻辑u128:大额金融计算、科学计算u256:加密计算、需要极大数值的特殊场景
有符号整型家族(Move 2.3新增):i8/i16/i32/i64/i128/i256
从Move 2.3开始,Move引入了有符号整数类型,用于表示正负数。
类型范围(以i8为例):
i8: -128 到 127i16: -32,768 到 32,767i32: -2,147,483,648 到 2,147,483,647i64: -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807i128: -2^127 到 2^127-1i256: -2^255 到 2^255-1
布尔值:bool
布尔类型只有两个值:true和false,用于逻辑判断。
地址:address
地址类型表示Aptos区块链上的账户地址。地址是256位(32字节)的值,通常以十六进制表示。
@0x1:Aptos标准库地址@0x2:Aptos框架地址@0x3:Aptos区块元数据地址@0x4:Aptos字符串操作地址
关键类型:signer详解
signer是Move中一个特殊且重要的类型,它代表交易的发送者(签名者)。
signer与address的核心区别:
| 特性 | signer | address |
|---|---|---|
| 本质 | 权限的证明 | 位置的标识 |
| 获取方式 | 只能作为入口函数参数传入 | 可以直接使用或计算 |
| 能做什么 | 授权操作、支付Gas、代表用户行动 | 仅作为目标标识 |
| 可变性 | 不可变引用(&signer) | 普通值 |
signer是”谁在执行操作”的证明。当函数需要&signer参数时,意味着这个函数需要调用者的明确授权。
动态数组:vector
vector是Move中唯一的集合类型,用于存储同类型元素的动态数组。
基础操作:
vector索引从0开始,访问越界会导致交易中止。总是检查索引是否有效!
🍳 厨师提示:Move中为什么没有字符串类型?
这是一个常见问题。Move没有内置的string类型,原因如下:
- 性能考虑:字符串操作(拼接、分割、编码转换)在区块链上成本高昂
- 确定性需求:智能合约需要确定性的执行结果,字符串处理的复杂性可能导致不确定性
- 实际用途:大多数合约场景只需要短标识符(名称、符号、URI)
- 短文本:使用
vector<u8>,如b"APT"(字节字符串字面量) - 标识符:通常足够用
vector<u8>表示 - 长文本/富文本:存储哈希值在链上,完整内容存储在链下(如IPFS、Arweave)
2.2 流程控制 (Flow Control)
条件分支:if/else if/else
Move的条件语句与其他语言类似,但有一些独特之处:
if可以返回值,但所有分支必须返回相同类型。
if表达式必须用分号结束,除非它是函数体的最后一条语句。
循环结构:while与loop
while循环:在条件为真时重复执行
break使用
控制流语句:break、continue、return、abort
break:立即退出当前循环continue:跳过当前循环剩余部分,进入下一次迭代return:从函数中返回(可带返回值)abort:中止整个交易,可带错误码
最佳实践:避免无限循环的几种模式
在区块链环境中,无限循环是危险的(可能消耗所有Gas或导致交易失败)。以下是安全模式: 模式1:最大迭代次数限制2.3 模块与函数 (Modules & Functions)
模块定义:module语法与命名规则
模块是Move代码的组织单元,类似于其他语言中的包或命名空间。
基本语法:
- 模块名应该小写,使用下划线分隔单词(snake_case)
- 模块名在同一个地址下必须唯一
- 建议使用有意义的名称,反映模块功能
可见性修饰符:public、public(friend)
Move 2.0中的可见性系统:
- 私有(默认):仅在模块内可见
public:任何模块都可调用public(friend):仅友元模块可调用
函数定义:参数、返回值、可见性
基本语法:重点:入口函数 entry 详解
入口函数是可以直接从外部交易调用的函数。这是Move 2.0的一个重要变化。
Move 2.0的变化:
- Move 1.0:使用
public(script)函数 - Move 2.0:使用
public函数,可标记为entry(可选但推荐)
- 必须是
public函数 - 不能有显式返回值(返回
()) - 通常第一个参数是
&signer(但不是强制的) - 所有参数必须是具体类型(不能是泛型)
entry?
- 明确性:清晰表明哪些函数是外部接口
- 工具支持:IDE和工具可以识别入口函数
- 最佳实践:鼓励良好的模块设计
实战练习:编写一个数学工具模块
现在,让我们综合运用所学知识,编写一个实用的数学工具模块。📝 本章总结
恭喜!你已经掌握了Move语言的基础语法: ✅ 基本数据类型:整型、布尔值、地址、signer、vector✅ 流程控制:条件语句、循环、控制流语句
✅ 模块与函数:模块组织、函数定义、可见性、入口函数 关键收获:
- 类型安全:Move是静态类型语言,编译时会进行严格检查
- 资源意识:虽然本章没有涉及资源,但数据类型的选择会影响后续的资源设计
- 模块化思维:通过模块组织代码,通过可见性控制访问权限
- 入口点设计:
entry函数是合约与外部世界的桥梁
- 尝试修改数学工具模块,添加更多函数(如计算平方根、幂运算)
- 创建自己的工具模块,包含处理
vector的实用函数 - 尝试使用泛型编写更通用的函数
- 忘记
if语句结尾的分号 - 在循环中忘记更新循环变量,导致无限循环
- 混淆
signer和address的使用场景 - 访问
vector时未检查索引边界
👨🍳 厨师笔记:
当我第一次学习这些基础语法时,最让我困惑的是signer类型。为什么需要这么复杂的权限系统?但当我开始编写真正的合约时,我意识到这正是Move的优雅之处——权限在类型系统中得到体现,而不是通过隐式的msg.sender。这种设计让安全漏洞在编译期就被发现,而不是在运行时造成损失。
记住:好的基础是成为大厨的关键。花时间理解这些概念,编写小练习,你会发现在后续的复杂合约开发中事半功倍。如果有任何疑问,随时回到本章复习。休息一下,准备好进入Move最精彩的部分! 🎯