地址(Address)
address
是 Move 语言的内置类型,用于表示全局存储中的位置(有时称为账户).一个 address
值是一个 256 位(32 字节)的标识符.在给定地址下可以存储两种内容:模块和资源.
虽然 address
底层实现是 256 位整数,但 Move 地址被设计为不透明的——它们不能从整数创建,不支持算术运算,也不可修改.尽管某些场景可能需要这类特性(例如 C 语言中的指针算术就有类似用途),但 Move 出于支持静态验证的设计目标,不允许这种动态行为.
你可以在运行时使用地址值(address
类型)来访问该地址下的资源,但_无法_通过地址值在运行时访问模块.
地址及其语法
Section titled “地址及其语法”地址有两种形式:命名地址和数值地址.命名地址的语法遵循 Move 中命名标识符的通用规则.数值地址的语法不限于十六进制值,任何有效的 u256
数值都可以作为地址值,例如 42
,0xCAFE
和 2021
都是有效的数值地址字面量.
为区分地址是否在表达式上下文中使用,其语法会根据使用场景有所不同:
通常可以将 @
视为一个运算符,它将地址从命名空间项转换为表达式项.
命名地址允许在任何使用地址的地方用标识符替代数值,而不仅限于值层面.命名地址在 Move 包中作为顶层元素(模块和脚本之外)声明和绑定,或作为参数传递给 Move 编译器.
命名地址仅存在于源代码层面,在字节码层面会被完全替换为其对应的数值.因此,模块和模块成员_必须_通过模块的命名地址访问,而不能通过编译时分配给命名地址的数值访问.例如,即使 Move 程序编译时将 my_addr
设为 0x2
,use my_addr::foo
也_不等同_于 use 0x2::foo
.这个区别在模块与脚本章节有更详细的讨论.
script { fun example() { let a1: address = @0x1; // 0x0000000000000000000000000000000000000000000000000000000000000001 的简写 let a2: address = @0x42; // 0x0000000000000000000000000000000000000000000000000000000000000042 的简写 let a3: address = @0xDEADBEEF; // 0x00000000000000000000000000000000000000000000000000000000DEADBEEF 的简写 let a4: address = @0x000000000000000000000000000000000000000000000000000000000000000A; let a5: address = @std; // 将命名地址 `std` 的值赋给 `a5` let a6: address = @66; let a7: address = @0x42; }}
module 66::some_module { // 非表达式上下文,无需 @ 前缀 use 0x1::other_module; // 非表达式上下文,无需 @ 前缀 use std::vector; // 引用其他模块时可将命名地址作为命名空间项使用 ...}
module std::other_module { // 声明模块时可将命名地址作为命名空间项使用 ...}
全局存储操作
Section titled “全局存储操作”address
值的主要用途是与全局存储操作进行交互.
address
值会与 exists
,borrow_global
,borrow_global_mut
和 move_from
操作 一起使用.
唯一 不 使用 address
的全局存储操作是 move_to
,该操作使用 signer
.
与语言中内置的其他标量值一样,address
值是隐式可复制的,这意味着它们无需显式指令(如 copy
)即可被复制.