模块
模块 是 Move 代码组织的基本单位。它们类似于其他编程语言中的命名空间或包,允许将相关的代码组合在一起,并控制代码的可见性和可访问性。模块定义了 类型、函数 和 常量,并使用 module
关键字在文件级别声明。
模块声明
模块声明的语法如下:
move
module <地址>::<模块名> {
// 模块成员
}
其中:
<地址>
是模块所属的地址。可以使用地址字面量(例如0x1
)或在Move.toml
文件中定义的命名地址。<模块名>
是模块的名称,必须是有效的 Move 标识符。
示例:
move
module 0x1::my_module {
// 模块成员
}
模块地址
模块地址可以是以下两种形式:
- 地址字面量: 直接使用十六进制地址表示,例如
0x1
。 - 命名地址: 在
Move.toml
文件的[addresses]
部分中定义的别名,例如my_package
。
模块成员
模块成员包括:
- 常量: 使用
const
关键字声明,表示不可修改的值。 - 结构体: 使用
struct
关键字声明,用于定义自定义数据类型。 - 函数: 使用
fun
关键字声明,用于定义可执行的代码块。
示例:
move
module book::my_module;
const MY_CONSTANT: u64 = 100;
struct MyStruct {
value: u64,
}
fun my_function(x: u64): u64 {
x + MY_CONSTANT
}
可见性
默认情况下,模块成员是 私有 的,只能从同一模块内部访问。Move 提供了以下可见性修饰符来控制模块成员的访问范围:
public
:将模块成员公开,允许从任何地方访问。- 包可见性:引入于 Move 2024,允许模块成员在同一包内的其他模块访问。
- 私有:没有任何修饰符,成员只能在定义它的模块内部访问。
包可见性
包可见性 是指模块成员可以被同一包内的其他模块访问,但不能从其他包中访问。包可见性通过 public(package)
修饰符声明。
语法:
move
public(package) fun 函数名() { /* ... */ }
示例
假设我们有一个名为 book
的包,其中包含两个模块 package_visibility
和 try_calling_package
。
文件结构:
book/
│── Move.toml
└── sources/
│── package_visibility.move
└── try_calling_package.move
package_visibility.move
:
move
module book::package_visibility {
// 包可见性函数:只能在同一包内访问
public(package) fun package_only() {
// ...
}
}
try_calling_package.move
:
move
module book::try_calling_package;
fun try_calling_package() {
// 同一包内,可以调用包可见性函数
package_visibility::package_only();
}
说明:
- 在
package_visibility
模块中,package_only
函数被声明为public(package)
,这表示它具有包可见性。 - 在
try_calling_package
模块中,由于两个模块属于同一个包book
,因此可以成功调用package_only
。 - 如果尝试从其他包的模块中访问
package_only
,将会导致编译错误,因为包可见性仅限于包内部。
模块初始化函数
模块可以定义一个名为 init
的特殊函数,该函数在模块发布时调用一次。 init
函数用于初始化模块的状态,例如创建资源或设置初始配置。
init
函数的规则:
- 函数名必须为
init
。 - 函数必须是 私有 的(使用
fun
关键字声明)。 - 函数不能有返回值。
- 函数可以接受一个或两个参数:一个是可选的 一次性见证 (One Time Witness, OTW),另一个是
TxContext
。其中TxContext
始终是最后一个参数。
示例:
move
module book::init_example {
fun init(ctx: &mut TxContext) {
// 初始化模块状态
}
}
总结
- 模块 是 Move 代码组织的基本单位,用于封装相关代码并控制代码的可见性和可访问性。
- 模块可以定义 常量、结构体 和 函数,并使用
module
关键字声明。 - 模块地址 可以使用地址字面量或命名地址表示。
- 模块成员 默认是私有的,可以使用
public
和public(package)
修饰符控制可见性。 - 包可见性 (
public(package)
) 允许模块成员在同一包内的其他模块访问,但不能从其他包访问。 - 模块可以定义一个名为
init
的初始化函数,该函数在模块发布时调用一次。