MoonBit 语言导览 MoonBit

let 和 match 中的模式

有两个常见的地方可以使用模式:letmatch

在这个例子中,我们定义了一个描述文件系统的 Resource 类型。 Resource 可以是文本文件、图像或包含更多文件的文件夹。

let 语句中的模式

let 语句中,= 左边可以是一个模式。 我们知道 assets 是一个文件夹,所以我们只需使用 let Folder(top_level) = assets 来匹配它并将值提取到不可变变量 top_level 中。

你可能会注意到有一个部分匹配警告,因为资源也可以是 ImageTextFile部分匹配使程序更加脆弱:模式匹配可能在其他情况下失败并导致程序中止。 实际上,match 表达式比 let 语句更常用。

match 表达式中的模式

count 函数递归地遍历输入 res 并返回 ImageTextFile 的计数,使用 match 表达式。

匹配表达式具有第一个匹配语义。它们将尝试从第一个情况到最后一个情况按顺序找到第一个匹配的模式并执行相应的匹配表达式。如果没有模式匹配,程序将中止。

匹配表达式具有 Int 返回值,因为所有情况都产生相同的值类型 Int

模式支持嵌套匹配。当不需要处理枚举构造器关联的具体数据时,可使用通配符模式_(下划线)代替变量绑定,该符号表示直接丢弃对应数据值。

enum Resource {
  TextFile(String)
  Image(String)
  Folder(Map[String, Resource])
}

let assets : Resource = Folder(
  {
    "readme.md": TextFile("hello world"),
    "image.jpg": Image("https://someurl1"),
    "folder1": Folder(
      {
        "src1.mbt": TextFile("some code1"),
        "src2.mbt": TextFile("some MoonBit code 2"),
      },
    ),
    "folder2": Folder(
      {
        "src3.mbt": TextFile("some code3"),
        "image2.jpg": Image("https://someurl2"),
      },
    ),
  },
)

fn main {
  let Folder(top_level) = assets
  println("we have items in the root folder:\n \{top_level.keys()}")
  println("resource count: \{count(assets)}")
}

fn count(res : Resource) -> Int {
  match res {
    Folder(map) => {
      let mut sum = 0
      for name, res in map {
        sum += count(res)
      }
      sum
    }
    TextFile(_) => 1
    Image(_) => 1
  }
}