Move 编码约定

Move 编码约定 #

本节列出了 Move 团队认为有用的一些基本的 Move 编码约定。这些只是建议,如果你喜欢其他格式指南和约定,你可以随时使用它们。

命名 #

  • 模块名称:应该使用小写的蛇形命名法,例如:fixed_point32vector
  • 类型名称:如果不是原生数据类型,则应使用驼峰命名法,例如:CoinRoleId
  • 函数名称:应该使用小写的蛇形命名法,例如:destroy_empty
  • 常量名称:应该使用大写的蛇形命名法,例如:REQUIRES_CAPABILITY
  • 泛型类型应该具备描述性,当然在适当的情况下也可以是反描述性的,例如:Vector 泛型类型的参数可以是 TElement。大多数情况下,模块中的“主”类型命名应该与模块名相同,例如:option::Optionfixed_point32::FixedPoint32
  • 模块文件名称:应该与模块名相同,例如:Option.move
  • 脚本文件名称:应该使用小写的蛇形命名法,并且应该与脚本中的“主”函数名匹配。
  • 混合文件名称:如果文件包含多个模块和/或脚本,文件命名应该使用小写的蛇形命名法,并且不需要与内部的任何特定模块/脚本名匹配。

导入 #

  • 所有模块的 use 语句都应该位于模块的顶部。
  • 函数应该从声明它们的模块中完全限定地导入和使用, 而不是在顶部导入。
  • 类型应该在顶部导入。如果存在名称冲突,应使用 as 在本地适当地重命名类型。

例如,如果有一个模块:

module 0x1::foo {
    struct Foo { }
    const CONST_FOO: u64 = 0;
    public fun do_foo(): Foo { Foo{} }
    ...
}

此时将被导入并使用:

module 0x1::bar {
    use 0x1::foo::{Self, Foo};

    public fun do_bar(x: u64): Foo {
        if (x == 10) {
            foo::do_foo()
        } else {
            abort 0
        }
    }
    ...
}

并且,如果在导入两个模块时存在本地名称冲突:

module other_foo {
    struct Foo {}
    ...
}

module 0x1::importer {
    use 0x1::other_foo::Foo as OtherFoo;
    use 0x1::foo::Foo;
    ...
}

注释 #

  • 每个模块、结构体和公共函数声明都应该有对应的注释。
  • Move 有文档注释 ///,常规单行注释 //,块注释 /* */,和块文档注释 /** */

格式化 #

Move 团队计划编写一个自动格式化程序来执行格式化约定。然而,在此期间:

  • scriptaddress 块外,其他的内容应使用四个空格的缩进。
  • 每行代码,如果超过 100 个字符,应该换行。
  • 结构体和常量应该在模块中的所有函数之前声明。