通过match看rust
最常见的逻辑控制流比如if-else,switch,while等常用编程语言都支持,但恰巧rust语法中没有switch,取而代之的是更加强大适用的match匹配,我们就来看看rust的match有何奇特之处。
一、介绍
先来看一个简单的rust的match用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | enum Role{ Admin, User, Guest, Unkown } fn main(){ let role=Role::Admin; match role{ Role::Admin=>println!( "you're an admin." ), Role::User=>println!( "you're a user." ), Role::Guest=>println!( "you're a guest." ), _=>println!( "deny to access." ) } } |
从这个例子可以看出,rust的match跟其它常用语言的switch功能相似。都是根据条件匹配分支。
比如C#实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum { Admin, User, Guest, Unkown } void Main(){ var role=Role.Admin; switch (role) { case Role.Admin:{Console.WriteLine( "you're an admin." ); break ;} case Role.User:{Console.WriteLine( "you're an user." ); break ;} case Role.Guest:{Console.WriteLine( "you're an guest." ); break ;} default :{Console.WriteLine( "deny to access." ); break ;} } } |
当然rust的match肯定不止于此,我们接着来看。
二、match配合变体enum解构
rust的变体enum可以包含不同数据类型,再加上match匹配可以轻松实现复杂的逻辑需求。
我们还是来看个例子,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | enum Operator{ Plus(i32,i32), Subtract(i32,i32), Multiply(i32,i32), Divide(i32,i32), Log10(i32) } fn main(){ let op=Operator::Plus(100,200); match op{ Operator::Plus(a,b)=>println!( "{a}+{b}={}" ,a+b), Operator::Subtract(a,b)=>println!( "{a}-{b}={}" ,a-b), Operator::Multiply(a,b)=>println!( "{a}x{b}={}" ,a*b), Operator::Divide(a,b)=>println!( "{a}/{b}={}" ,a/b), Operator::Log10(a)=>println!( "log10({a})={}" ,a.ilog10()), } } |
类似这样的需求还是比较多的,比如处理鼠标事件
1 2 3 4 5 6 | enum MouseEvent{ MoveIn, MoveOut, Click(x,y), ... } |
像这个例子在面向对象的编程语言中,肯定是使用类型继承实现来到达目的,继承并非不好,而是组合才是更佳思维方式,就好比社会各种组织都是靠协作,而非强行大一统,每个部分都有自身最高效的运作方式,强行一致这样的组织也效率低下。
三、复杂match匹配臂
1、匹配区间模式
1 2 3 4 5 6 7 8 | fn main() { let num=100; match num{ x @ 1 ..=3| x @ 6 ..=9=>println!( "case 1.{x}" ), 4|5=>println!( "case 2.b" ), x=>println!( "case 3.{x}" ) } } |
2、匹配通配符模式
1 2 3 4 5 6 7 8 9 | fn main(){ let test=vec![ "b" , "m" , "r" , "x" , "n" , "t" , "f" , "j" ]; let s=(2,3,&test[0..3]); match s{ (_,3,[.., "j" ])=>println!( "case 1." ), (2,_,[ "rust" ,end @ ..])=>println!( "case 2.{:?}" ,end), (_,_,_)=>println!( "case 3." ), } } |
当然还有一些其它的模式匹配就不一一说明了。
四、用match消除if-else
if-else是所有编程语言中最简单直接的逻辑流控制方式,以至于被滥用了,在加上变量命名随意,词不达意使得代码难以理解(最近自嘲的”防御式编程“例外),说实话三层if-else就足以让人琢磨,我曾见到过十几层的if-else,一个方法上千行,再后来曾几何时编程流行消除if-else,以C++,Java,C#等流行面向对象语言大多使用设计模式来消除if-else,以至于设计模式被滥用了。
if-else并非是恶,既然提供了当用则用,无需顾虑太多。
在rust中对于单个Option<T>还是推荐用if let方式处理比较简单,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [Debug] struct User{ user_name:String, age:u8 } fn get_user(user_name:&str,pwd:&str)->Option<User>{ if user_name== "admin" && pwd== "123456" { Some(User{user_name,age:20}) } else { None } } fn main(){ let user=get_user( "admin" , "123456" ); if let Some(user)=user{ println!( "login success {:?}" ,user); } } |
我们应该谨防的是一个函数大段代码多层if-else嵌套,这个就是坏味道了。在其它常用编程语言中可能我们会用if-else写出这样的代码,伪代码比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if user.phone!= null { if user.email!= null { send_message(user.phone); send_email(user.email); log( "优质客户" ); } else { send_message(user.phone); log( "普通客户" ); } } else { if user.email!= null { send_email(user.email); log( "一般客户" ); } else { log( "待发展客户" ); } } |
if-else是不是看得眼都花了,如果逻辑再复杂一些,这样的if-else嵌套更多层,人都麻了,不上个设计模式都有点不好意思了。
我们来用rust的mach匹配看看如何消除使得代码更加清晰直观。伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | struct User{ phone:Option<String>, email:Option<String> } fn main(){ let user=User{phone:None,email: "bm@vv.com" .to_owned()}; match(user.phone,user.email){ (Some(phone),Some(emial))=>{ send_message(user.phone); send_email(user.email); log( "优质客户" ); }, (Some(phone),None)=>{ send_message(user.phone); log( "普通客户" ); }, (None,Some(email))=>{ send_email(user.email); log( "一般客户" ); }, (_,_)=>log( "待发展客户" ) } } |
rust的match可以匹配多个目标,match使得层级单一了,整体逻辑是不是清晰多了。
好了,啰嗦了这么多,感谢各位看官驻足在此停留。
文章在博客园、微信公众号等平台发布,转载请注明来源(bmrxntfj)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探