https://aptos.dev/en/build/smart-contracts/book/coding-conventions
Move 编码规范
本节列出了一些 Move 的基本编码规范,Move 团队发现这些规范非常有帮助。这些只是建议,如果你有其他格式化指南和规范的偏好,随时可以使用。
命名
- 模块名称: 应使用小写蛇形命名法,例如
fixed_point32,vector。 - 类型名称: 如果不是原生类型,应使用驼峰命名法,例如
Coin,RoleId。 - 函数名称: 应使用小写蛇形命名法,例如
destroy_empty。 - 常量名称: 如果表示错误代码,应使用大写驼峰命名法并以
E开头(例如EIndexOutOfBounds);如果表示非错误值,则应使用大写蛇形命名法(例如MIN_STAKE)。 - 泛型类型名称: 应具有描述性,或在适当情况下使用反描述性,例如,
T或Element用于向量泛型类型参数。通常情况下,模块中的“主要”类型应与模块同名,例如option::Option,fixed_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 0x1::other_foo { struct Foo {} // ...} module 0x1::importer { use 0x1::other_foo::Foo as OtherFoo; use 0x1::foo::Foo; // ...}
注释
- 每个模块、结构体和公共函数声明应有注释。
- Move 有文档注释
///、常规单行注释//、块注释/* */和块文档注释/** */。
注释示例
文档注释必须直接位于它们所注释项的上方。例如,以下是有效的:
/// 我的精彩模块,文档注释可以在这里使用
module 0x42::example { // 双斜杠可以在任何地方
// 双斜杠可以在任何地方
/// 我精彩的常量
const MY_VALUE: u64 = 5;
/// 我精彩的错误信息
const E_MY_ERROR: u64 = 10;
#[view]
/// 我精彩的视图函数
fun show_me_the_money() {
// ...
}
/* 同样,块注释可以在任何地方 */
}
下面是一些文档注释 /// 将会失败的示例:
module 0x42::example {
/// 我精彩的视图函数 <- 必须在注解下方,正好位于被注释项上方
#[view]
fun show_me_the_money() {
// ...
/// 在函数内部
}
/// 没有附加到任何东西
}
格式化
Move 团队计划编写一个自动格式化工具来强制执行格式化规范。然而,在此之前:
- 除了
script和address块的内容不应缩进外,其他地方应使用四个空格的缩进。 - 如果行超过 100 个字符,应进行换行。
- 结构体和常量应在模块中的所有函数之前声明。