模块

模块是发布在特定地址下的打包在一起的一组函数和结构体。

模块在发布者的地址下发布。标准库在 0x1 地址下发布。

发布模块时,不会执行任何函数。要使用模块就得使用脚本。

模块以module关键字开头,后面跟随地址::模块名称和大括号,大括号中放置模块内容。

模块名推荐使用小写

module book::math {
    public fun sum(a: u64, b: u64): u64 {
        a + b
    }
}

模块是发布代码供他人访问的唯一方法。新的类型和 Resource 也只能在模块中定义。默认情况下,模块将在发布者的地址下进行编译和发布

如示例所示:最佳实践是保持模块行不缩进

导入

Move 在默认上下文中只能使用基本类型,也就是整型、布尔型和地址,可以执行的有意义或有用的操作也就是操作这些基本类型,或者基于基本类型定义新的类型。

除此之外还可以导入已发布的模块(或标准库)。

直接导入

可以直接在代码中按其地址使用模块:

module book::m {
    fun main(a: u8) {
        std::debug::print(&a);
    }
}

在此示例中,我们从地址0x1(标准库)导入了 debug 模块,并使用了它的 print 方法。

关键字 use

要使代码更简洁(注意,0x1 是特殊的地址,实际地址是很长的),可以使用关键字use:

use <address>::<ModuleName>;

这里 <address> 是模块发布object的地址,<ModuleName> 是模块的名字。非常简单,例如,我们可以像下面这样从 0x1 地址导入 vector 模块。

use 0x1::vector;

访问模块的内容

要访问导入的模块的方法(或类型),需要使用::符号。非常简单,模块中定义的所有公开成员都可以通过双冒号进行访问。

module book::m_use {
    use  std::debug::print;
    fun main(a: u8) {
        print(&a);
    }
}

在模块中导入

在模块中导入模块必须在 module {} 块内进行:

module book::math {
    use std::vector;
    // you are free to import any number of modules
    public fun empty_vec(): vector<u64> {
        let v = vector::empty<u64>();
        v
    }
}

成员导入

导入语句还可以进一步被扩展,可以直接导入模块的成员:

module book::m_use2 {
    // single member import
    use sui::tx_context::TxContext;
    use sui::tx_context::sender;

    // multi member import (mind braces)
    use std::vector::{
        empty,
        push_back
    };

    fun main(ctx: &mut TxContext) {
        // use functions without module access
        let vec = empty<u8>();
        push_back(&mut vec, 10);
        let _ = sender(ctx);
    }
}

使用 Self 来同时导入模块和模块成员

导入语句还可以进一步扩展,通过使用 Self 来同时导入模块和模块成员,这里 Self 代表模块自己。

module book::m_self {

    use 0x1::vector::{
    Self, // Self == Imported module
    empty
    };

    fun main() {
        // `empty` imported as `empty`
        let vec = empty<u8>();
        // Self means vector
        vector::push_back(&mut vec, 10);
    }
}

使用 use as

当两个或多个模块具有相同的名称时,可以使用关键字as更改导入的模块的名称,这样可以在解决命名冲突的同时缩短代码长度。

语法:

use <address>::<ModuleName> as <Alias>;

在模块中:

module ch04::m_as {
    use 0x1::vector as v;

    // v now means vector
    fun main() {
        v::empty<u64>();
    }
}

脚本中的例子:

module ch04::m_as1 {
    use 0x1::vector::{
    Self as v,
    empty as empty_vec
    };

    fun main() {
        // `empty` imported as `empty_vec`
        let vec = empty_vec<u8>();

        // Self as V = vector
        v::push_back(&mut vec, 10);
    }
}