Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

模块(Module)

模块(Module)是 Move 语言中代码组织的基本单元,用于将相关的类型定义、函数和常量组织在一起。模块为代码提供了命名空间隔离,所有成员默认是私有的,只有显式标记为 public 的成员才能被外部访问。理解模块的声明方式和组织规范是学习 Move 语言的第一步。

模块声明语法

每个 Move 源文件通常包含一个模块声明。模块声明的基本语法如下:

module package_address::module_name;

其中 package_address 是包地址(可以是字面地址或命名地址),module_name 是模块名称。

2024 标签语法与传统语法

在 Move 2024 版本中,推荐使用上面的标签语法(label syntax),以分号结尾,模块体中的代码直接写在文件中,无需大括号包裹。

传统语法(pre-2024)使用大括号包裹模块体:

module book::my_module {
    // 模块内容全部在大括号内
    public fun hello(): u64 { 42 }
}

本书统一使用 2024 标签语法。

命名规范

Move 模块遵循 snake_case(蛇形命名法)规范,即全部小写字母,单词之间以下划线分隔:

  • my_module
  • token_swap
  • MyModule
  • tokenSwap

通常建议 一个文件只包含一个模块,文件名与模块名保持一致。例如模块 my_module 对应文件 my_module.move

模块成员

一个模块可以包含以下成员:

  • 结构体(Struct):自定义数据类型
  • 函数(Function):可执行的逻辑单元
  • 常量(Constant):编译时确定的不可变值
  • 导入(Use):引用其他模块的成员
module book::my_module;

use std::string::String;

const MAX_SIZE: u64 = 100;

public struct Item has key, store {
    id: UID,
    name: String,
}

public fun create_item(name: String, ctx: &mut TxContext): Item {
    Item {
        id: object::new(ctx),
        name,
    }
}

上面的示例展示了一个完整的模块,包含了导入、常量、结构体和函数。

地址与命名地址

模块必须属于一个地址。地址可以是字面地址或命名地址。

字面地址

字面地址是一个十六进制值,例如 0x00x10x2

module 0x1::math;

命名地址

命名地址是在 Move.toml 配置文件中定义的别名,更加可读且便于管理:

# Move.toml
[addresses]
book = "0x0"
std = "0x1"
sui = "0x2"

使用命名地址声明模块:

module book::my_module;

编译时,book 会被替换为 Move.toml 中定义的实际地址 0x0。命名地址的好处是在发布合约后只需修改 Move.toml 中的地址,而不需要修改源代码。

访问控制

模块中的所有成员默认是 私有的,即只能在定义它们的模块内部访问:

module book::access_control;

// 私有函数,只能在本模块内调用
fun internal_logic(): u64 {
    42
}

// 公开函数,可以被其他模块调用
public fun value(): u64 {
    internal_logic()
}

// 仅供 package 内其他模块调用
public(package) fun package_only(): u64 {
    100
}

Move 提供了三种可见性级别:

可见性关键字访问范围
私有(无修饰符)仅模块内部
公开public任何模块
包级别public(package)同一个包内的模块

小结

模块是 Move 语言的代码组织基石。本节的核心要点包括:

  • 模块使用 module address::name; 语法声明,推荐使用 2024 标签语法
  • 模块名遵循 snake_case 命名规范,一个文件对应一个模块
  • 模块可以包含结构体、函数、常量和导入
  • 地址可以是字面地址或 Move.toml 中定义的命名地址
  • 所有模块成员默认私有,需要显式标记 publicpublic(package) 来暴露