let 和 match 中的模式
有两个常见的地方可以使用模式:let
和 match
。
在这个例子中,我们定义了一个描述文件系统的 Resource
类型。
Resource
可以是文本文件、图像或包含更多文件的文件夹。
let 语句中的模式
在 let
语句中,=
左边可以是一个模式。
我们知道 assets
是一个文件夹,所以我们只需使用 let Folder(top_level) = assets
来匹配它并将值提取到不可变变量 top_level
中。
你可能会注意到有一个部分匹配警告,因为资源也可以是 Image
或 TextFile
。
部分匹配使程序更加脆弱:模式匹配可能在其他情况下失败并导致程序中止。
实际上,match
表达式比 let
语句更常用。
match 表达式中的模式
count
函数递归地遍历输入 res
并返回 Image
和 TextFile
的计数,使用 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
}
}