概述#

一个 MoonBit 程序由顶层定义组成,包括:

  • 类型定义

  • 函数定义

  • 常数定义和变量绑定

  • init 函数,main 函数和/或 test 块。

表达式和语句#

MoonBit 区分语句和表达式。在函数体中,只有最后一个子句应该是一个表达式,它作为返回值。例如:

fn foo() -> Int {
  let x = 1
  x + 1
}

fn bar() -> Int {
  let x = 1
  //! x + 1
  x + 2
}

表达式包括:

  • 值字面量(例如布尔值、数字、字符、字符串、数组、元组、结构体)

  • 算术、逻辑或比较操作

  • 访问数组元素(例如 a[0]),结构体字段(例如 r.x),元组组件(例如 t.0)等。

  • 变量和枚举构造器

  • 匿名本地函数定义

  • matchifloop 表达式等。

语句包括:

  • 命名本地函数定义

  • 本地变量绑定

  • 赋值

  • return 语句

  • 任何返回类型为 Unit 的表达式(例如 ignore

代码块可以包含多个语句和一个表达式,表达式的值是代码块的值。

变量绑定#

变量可以使用 let mutlet 声明为可变或不可变。可变变量可以重新赋值为新值,而不可变变量则不能。

常量只能在顶层声明,不能更改。

let zero = 0

const ZERO = 0

fn main {
  //! const ZERO = 0 
  let mut i = 10
  i = 20
  println(i + zero + ZERO)
}

备注

顶层变量绑定

  • 需要 显式 类型注释(除非使用字符串、字节或数字等字面量定义)

  • 不能是可变的(使用 Ref 代替)

命名约定#

变量、函数应以小写字母 a-z 开头,可以包含字母、数字、下划线和其他非 ASCII 的 Unicode 字符。建议使用 snake_case 命名。

常量、类型应以大写字母 A-Z 开头,可以包含字母、数字、下划线和其他非 ASCII 的 Unicode 字符。建议使用 PascalCase 或 SCREAMING_SNAKE_CASE 命名。

程序入口#

initmain#

有一个专门的函数称为 init 函数。init 函数是特殊的:

  1. 它没有参数列表也没有返回类型。

  2. 同一个包中可以有多个 init 函数。

  3. init 函数不能被显式调用或被其他函数引用。相反,所有 init 函数将在初始化包时隐式调用。因此,init 函数应该只包含语句。

fn init {
  let x = 1
  println(x)
}

还有另一个专门的函数称为 main 函数。main 函数是程序的主入口,它将在初始化阶段之后执行。

init 函数相同,它没有参数列表也没有返回类型。

fn main {
  let x = 2
  println(x)
}

前两个代码片段将在运行时打印以下内容:

1
2

只有 main 包的包才能定义这样的 main 函数。查看构建系统教程了解详情。

moon.pkg.json#
{
  "is-main": true
}

test#

还有一个称为 test 块的顶级结构。test 块定义内联测试,例如:

test "test_name" {
  assert_eq!(1 + 1, 2)
  assert_eq!(2 + 2, 4)
  inspect!([1, 2, 3], content="[1, 2, 3]")
}

以下内容将使用 test 块和 main 函数来演示执行结果。我们假设所有 test 块都通过测试,除非另有说明。