MoonBit 开发规范与辅助
本技能为 MoonBit(月兔)开发提供统一编码规范与最新语法/类库参考。所有语句均以
MoonBit 官方文档最新稳定版本(当前基于 v0.10+)与 moonbitlang/core 为准,帮助写出可编译、可测试、符合社区惯例的代码。
核心原则:MoonBit 是面向表达式(expression-oriented)、引用语义(有 GC,无生命周期/所有权标注)的语言; 错误处理是受检错误(checked errors);类型是一等公民,配合强大的模式匹配与 trait 系统。
何时使用
当用户请求涉及以下内容时,加载本技能并按其中规范执行:
- 编写、修改、重构、审查 MoonBit 代码(
.mbt、.mbt.md、.mbtp) - 搭建 MoonBit 项目(
moon new、模块/包结构、moon.mod/moon.pkg配置) - 构建、运行、测试、检查、格式化(
moon系列命令) - 使用标准库
moonbitlang/core的数据结构与工具 - 解释某段 MoonBit 语法或类库用法
强制编码规范(写代码必须遵守)
1. 命名与大小写
- 变量、函数、方法、字段:以小写字母开头,使用
snake_case。函数名绝不能以大写开头(否则编译错误)。 - 类型、常量、枚举变体(constructor)、trait:以大写字母开头,使用
UpperCamelCase/SCREAMING_SNAKE_CASE(常量)。 - 可见性由关键字控制,与大小写无关:默认
priv,对外暴露用pub(只读/限制构造)或pub(all)(允许外部构造)。
struct Student { id : String, score : Double }
enum ExamResult { Pass, Fail }
const MAX_SCORE = 100
fn is_qualified(stu : Student, criteria : Double) -> ExamResult { ... }
2. 绑定与可变性
let= 不可变绑定;let mut= 可变绑定;const= 顶层常量。- 顶层
let不可为mut,一般需要显式类型标注(除非是字面量)。 - 有 GC,无需所有权/生命周期标注。
let mut仅在你需要重新赋值变量时才用; 修改结构体字段或数组元素不需要mut,但可变字段本身要声明为mut。 - 共享可变状态用
Ref[T]({ val: x })。
3. 表达式导向(最重要)
- 函数体/代码块中,最后一条表达式即为返回值,不要滥用
return。 if、match、循环(while/for)都会返回值;if的分支期末类型需一致,else仅在返回Unit时可省略。
fn classify(x : Int) -> String {
if x > 0 { "positive" } else { "non-positive" } // 直接作为返回值
}
4. 结构体 / 枚举 / Newtype
- 结构体字段默认不可变,可变字段需标
mut。 - 字面量构造:
T::{ field: value },类型可推断时直接写{ field: value }。 - 元组结构体(newtype):
struct Age(Int),访问用.0,构造Age(25)。 - 枚举可携带载荷:
enum IntList { Nil, Cons(Int, IntList) }。 - 常用 derive:
derive(Eq, Compare, Debug, Default, Hash, Show, ToJson, FromJson)。
5. 函数与参数
- 顶层函数的参数与返回值必须显式类型标注;本地函数可类型推断。
- 方法定义为
fn TypeName::method(self, ...),可用点号x.method()或限定Type::method调用;方法支持重载。 - 命名参数:
labelled(opt~ : Int);可选参数opt? : Int = default。 - 回调优先用箭头函数
x => ...(支持效果推断);fn若会raise/async必须显式标注。 - 互递归本地函数用
letrec f = ... and g = ...。
6. 错误处理(受检错误)
- 所有错误都是
Error的子类型。自定义错误用suberror(新语法:suberror E { Con(payload) })。 - 声明可抛错函数:
fn f(...) -> T raise E;不抛错用noraise;错误多变体用raise Error或省略类型。 - 抛错用
raise E(...);便捷地使用fail("msg")(自动带源码位置)。 - 处理:
try { } catch { Pattern => ... } noraise { value => ... };转成Result用... catch { e => Err(e) }或用try?;直接失败用try!。 - 错误必须被显式处理,不能忽略。
suberror DivError { DivError(String) }
fn div(x : Int, y : Int) -> Int raise DivError {
if y == 0 { raise DivError("division by zero") }
x / y
}
fn main {
try div(42, 0) catch { DivError(s) => println(s) } noraise { v => println(v) }
}
7. 循环与控制流
- 优先使用函数式遍历:
for x in xs { }、for i, x in xs { }(遍历Iter,for k, v in map遍历Iter2)。 - 范围表达式:
a..<b(不含 b)、a..=b(含 b)、a>..b、a>=..b。 - C 风格
for i = 0; i < n; i = i + 1也可用;不能用++/--。 - 循环"正常结束"子句用
nobreak { }(旧else已废弃)。 - 列表推导:
[ for x in xs if cond => expr ]。 - 资源清理用
defer expr body。
8. Trait 与接口
- 定义
trait用pub(open) trait I { method(Self, ...) };Self指实现类型。 - Trait 继承:
trait Object: Position + Draw。 - 实现:
pub impl MyShow for MyType with method(self) { ... };实现 trait 后其方法自动可用点号调用,无需extend。 - 手写内置
Show:pub impl Show for T with output(self, logger) { ... }(to_string()自动派生);调试输出用Debug+debug_inspect(),不要为调试derive(Show)。 - 默认实现:声明处加
= _,实现impl J with f_twice(self)。 - 内置 trait:
Eq, Compare, Hash, Show, Default, Debug;运算符Add, Sub, Mul, Div, Mod, Neg, Shl, Shr, BitAnd, BitOr, BitXOr;序列化ToJson, FromJson。 - trait 对象:
t(实现了I)打包成t as &I;仅对象安全 trait 可用于 trait 对象。
9. 迭代器
- 内置
Iter[T](外部迭代器)与Iter2[A, B]。常用:each / fold / collect / filter / map / concat(filter/map惰性)。 - 几乎所有顺序数据结构都实现了
Iter;for .. in依赖结构的.iter()/.iter2()(或转换为视图后的迭代)自动遍历。
10. 工程与组织
- 多而内聚的小文件优于单一大文件;文件按功能命名(如
http_client.mbt),纯组织用途,不代表模块。 - 同包内可自由移动顶层声明(块之间用
///|分隔,移动不影响语义)。 - 测试:
*_test.mbt(黑盒测试,不能访问包内私有成员)、内联test "name" { ... }块、*.mbt.md(文档即测试)。跑测试用moon test。 - 跨包调用函数:在
moon.pkg中声明import并加别名,代码里用@alias.fn;不用手写import关键字。
11. 常见坑(避免)
- 函数/变量不要用大写开头(编译错误)。
- 可变字段或要重新赋值的变量记得
mut。 - 不要用
++/--;用i = i + 1或i += 1。 - 不要依赖旧语法
f!(...)/f(...)?(已废弃);错误用raise/try?体系。 - 不要简单地省略错误处理;所有
raise路径必须被处理。 FixedArray::make(n, value)所有元素共享同一对象;需独立对象用FixedArray::makei(n, fn(i){...})。- 顶层
let不能是mut,需显式类型(除非字面量)。 - 访问可能越界的数组下标时,优先安全方式(检查 length、使用
get()/ 视图)。
执行流程
- 识别场景:用户是要写新代码、改代码、解释、测试,还是搭项目/配环境。
- 查询参考:按需要读取
references/下的文档(syntax.md、stdlib.md、tooling.md、examples.md),确保用最新语法;查询具体标准库/依赖 API 优先用moon ide doc "..."(以本地工具链为准,比记忆更准确)。 - 编写/修改代码:严格遵循上述规范;生成代码时用
///|分隔顶层块,便于后续增量修改与测试。 - 验证:如环境可用,推荐用户运行
moon check/moon test/moon fmt校验(快照更新用moon test --update),警告/诊断含义用moon explain --diagnostic查询;给出可执行命令。 - 交付:说明改动点、为何符合最佳实践、如何运行与测试。
若代码涉及标准库具体 API,先查
references/stdlib.md与官方 mooncakes.io 文档,避免臆造函数名。
参考文档导航
references/syntax.md— 最新语法速查(类型、字面量、函数、控制流、模式匹配、trait、错误处理、字符串/字节)。references/stdlib.md— 标准库moonbitlang/core常用数据结构、prelude 名称、常用类库与序列化。references/tooling.md—moonCLI、模块moon.mod、包moon.pkg、工作区、目标平台、测试/覆盖率。references/examples.md— 完整可运行示例与最佳实践集合(CLI、全栈、错误处理、trait 等)。
官方权威来源:
- 官方文档:https://docs.moonbitlang.com/zh-cn/latest/
- 包/API 文档:https://mooncakes.io/
- 官网:https://www.moonbitlang.com/
微信扫一扫