@
wutiantong pattern match 的优越性是老生常谈了,各路 fp 语言都分别论证过一遍的东西,随手举几个例子
···
fn foobar(n: u8) -> String {
(match (n % 3, n% 5) {
(0, 0) => "foobar",
(0, _) => "foo",
(_, 0) => "bar",
(_, _) => ""
}).into()
}
struct List<T> {
value: T,
next: Option<Box<T>>
}
fn len<T>(list: List<T>) -> usize {
1 + match list {
List { value: Some(list), ...} -> len(list) ,
List { value: None, ...} -> 0
}
}
···
复杂的例子里最好的例子大概是 ast,比如
···
let persistent_id = match &mut item {
// function Foo() {}
ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { ident, .. }))) => {
if let Some(hook) = handle_map.remove(&ident) {
hook_reg.push((ident.clone(), hook));
}
get_persistent_id(ident)
}
// export function Foo() {}
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
decl: Decl::Fn(FnDecl { ident, .. }),
..
})) => {
if let Some(hook) = handle_map.remove(&ident) {
hook_reg.push((ident.clone(), hook));
}
get_persistent_id(ident)
}
// export default function Foo() {}
ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(ExportDefaultDecl {
decl:
DefaultDecl::Fn(FnExpr {
// We don't currently handle anonymous default exports.
ident: Some(ident),
..
}),
..
})) => {
if let Some(hook) = handle_map.remove(&ident) {
hook_reg.push((ident.clone(), hook));
};
get_persistent_id(ident)
}
// const Foo = () => {}
// export const Foo = () => {}
ModuleItem::Stmt(Stmt::Decl(Decl::Var(var_decl)))
| ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
decl: Decl::Var(var_decl),
..
})) => {
···
至于生命周期的例子,不好意思,cpp 只要愿意永远可以怼裸指针,而且 rust 里需要手动标记的地方也是越来越少,所以很难搞出一个具体的例子,不过你可以看看 rust 里的 COW 是怎么做的