Skip to content

模块

模块 是 Move 代码组织的基本单位。它们类似于其他编程语言中的命名空间或包,允许将相关的代码组合在一起,并控制代码的可见性和可访问性。模块定义了 类型、函数 和 常量,并使用 module 关键字在文件级别声明。

模块声明

模块声明的语法如下:

move
module <地址>::<模块名> {
    // 模块成员
}

其中:

  • <地址> 是模块所属的地址。可以使用地址字面量(例如 0x1)或在 Move.toml 文件中定义的命名地址。
  • <模块名> 是模块的名称,必须是有效的 Move 标识符。

示例:

move
module 0x1::my_module {
    // 模块成员
}

模块地址

模块地址可以是以下两种形式:

  1. 地址字面量: 直接使用十六进制地址表示,例如 0x1
  2. 命名地址: 在 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 提供了以下可见性修饰符来控制模块成员的访问范围:

  1. public:将模块成员公开,允许从任何地方访问。
  2. 包可见性:引入于 Move 2024,允许模块成员在同一包内的其他模块访问。
  3. 私有:没有任何修饰符,成员只能在定义它的模块内部访问。

包可见性

包可见性 是指模块成员可以被同一包内的其他模块访问,但不能从其他包中访问。包可见性通过 public(package) 修饰符声明。

语法:

move
public(package) fun 函数名() { /* ... */ }

示例

假设我们有一个名为 book 的包,其中包含两个模块 package_visibilitytry_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();
}

说明:

  1. package_visibility 模块中,package_only 函数被声明为 public(package),这表示它具有包可见性。
  2. try_calling_package 模块中,由于两个模块属于同一个包 book,因此可以成功调用 package_only
  3. 如果尝试从其他包的模块中访问 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 关键字声明。
  • 模块地址 可以使用地址字面量或命名地址表示。
  • 模块成员 默认是私有的,可以使用 publicpublic(package) 修饰符控制可见性。
  • 包可见性 (public(package)) 允许模块成员在同一包内的其他模块访问,但不能从其他包访问。
  • 模块可以定义一个名为 init 的初始化函数,该函数在模块发布时调用一次。