模式 
模式是Rust中特殊的语法,用来匹配值的结构 
组成: 
(1) 字面值 
(2) 解构的数组、枚举、结构体或者元组 
(3) 变量 
(4) 通配符 
(5) 占位符
 
match的例子 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn  main () {  let  a  = 1 ;   match  a {     0  => println! ("Zero" ),       1  => println! ("One" ),       _ => println! ("other value" ),   }; } 
 
if let 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 fn  main () {  let  color : Option <&str > = None ;   let  is_ok  = true ;   let  age : Result <u8 ,_> = "33" .parse ();   if  let  Some (c) = color {     println! ("color = {}" ,c);   } else  if   is_ok {     println! ("is ok" );   }else  if  let  Ok (a) = age {     if  a > 30  {       println! ("oh,mature man" );     }else  {       println! ("oh,young man" );     }   }else  {     println! ("is else" );   } } 
 
while let 
1 2 3 4 5 6 7 8 9 10 11 fn  main () {    let  mut  stack  = Vec ::new ();     stack.push (1 );     stack.push (2 );     stack.push (3 );     while  let  Some (top) = stack.pop () {         println! ("top = {}" ,top);       }   } 
 
for 
在for循环中模式是直接跟随for循环字 
此处的模式是(index,value)
 
1 2 3 4 5 6 fn  main () {    let  v  = vec! ['a' ,'b' ,'c' ];     for  (index,value) in  v.iter ().enumerate () {         println! ("index: {},value {}" ,index,value);       }   } 
 
let语句 
1 2 3 4 5 6 7 8 fn  main () {    let  (x,y,z) = (1 ,2 ,3 );      println! ("{},{},{}" ,x,y,z);          let  (x,..,z) = (1 ,2 ,3 );     println! ("{},{}" ,x,z);   } 
 
函数的模式 
1 2 3 4 5 6 7 8 9 fn  print_point  (&(x,y): &(i32 ,i32 )) {    println! ("x = {},y = {}" ,x,y);   } fn  main () {    let  p  = (3 ,5 );     print_point (&p);   } 
 
模式的可反驳和不可反驳 
模式有两种:refutable 和irrefutable(可反驳的和不可反驳的),能够匹配任何传递的可能值 
的模式叫做不可反驳模式,对值匹配可能失败的叫做可反驳模式
只能接受不可反驳模式的由: 函数、let语句、for循环,因为其通过不匹配的值程序无法进行有意义工作 
if let和while let表达式被限制为只能接受可反驳的模式,因为他们定义就是为了处理有可能失败的条件 
 
 
1 2 3 4 5 6 7 8 9 10 fn  main () {    let  a : Option <i32 > = Some (5 );      let  b : Option <i32 > = None ;                if  let  Some (v) = a {              println! ("v = {}" ,v);       }   } 
 
匹配字面值 
1 2 3 4 5 6 7 8 fn  main () {    let  x  = 1 ;     match  x {         1  => println! ("one" ),         2  => println! ("two" ),         - => println! ("xx" ),       };   } 
 
匹配命名变量 
1 2 3 4 5 6 7 8 9 10 11 fn  main () {    let  x  = Some (5 );     let  y  = 10 ;     match  x {         Some (50 ) => println! ("50" ),         Some (y) => println! ("y = {}" ,y),          _ => println! ("other" ),       };     println! ("x = {:?},y = {:?}" ,x,y);   } 
 
多个模式 
1 2 3 4 5 6 7 8 fn  main () {    let  x  = 1 ;     match  x {         1 |2  => println! ("1 or 2" ),          3  => println! ("3" ),         - => println! ("xx" ),       };   } 
 
通过…匹配 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 fn  main () {    let  x  = 5 ;     match  x {         1 ..=5  => println! ("1 to 5" ),                            - => println! ("xx" ),       };     let  x  = 'c' ;     match  x {         'a' ..='j'  => println! ("1" ),         'k' ..='z'  => println! ("2" ),         _ => println! ("other" ),       };   } 
 
解构并分解值 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 struct  Point  {    x: i32 ,     y: i32 ,   } fn  main () {          let  p  = Point {x: 1 ,y: 2 };     let  Point {x:a,y:b} = p;     let  Point {x:x,y:y} = p;     assert_eq! (1 ,x);     assert_eq! (1 ,y);     assert_eq! (1 ,a);     assert_eq! (2 ,b);   } 
 
1 2 3 4 5 6 7 let  p  = Point {x:1 ,y:0 };match  p {    Point {x=0 ,y=0 } => println! ("原点" ),     Point {x,y:0 } => println! ("x axis" ),     Point{x=0 ,y} => println! ("y axis" ),     Point {x,y} => println! ("other" ),   }; 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 enum  Message  {    Quit,      Move{x: i32 ,y: i32 },     Write (String ),     ChangeColor{i32 ,i32 ,i32 },   } fn  main () {    let  msg  = Message::ChangeColor (0 ,160 ,255 );     match  msg {         Message::Quit => {             println! ("quit" );           },         Message::Move{x,y} => {println! ("move x {} y {}" ,x,y);},         Message::Write (text) => println! ("write msg = {}" ,text),         Message::ChangeColor (r,g,b) => {             println! ("color, r = {},g = {},b= {}" ,r,g,b);           },       };   } 
 
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 enum  Color  {    Rgb (i32 ,i32 ,i32 ),     Hsv (i32 ,i32 ,i32 ),   } enum  Message  {    Quit,      Move{x: i32 ,y: i32 },     Write (String ),     ChangeColor (Color),   } fn  main () {    let  msg  = Message::ChangeColor (Color::Hsv (0 ,160 ,255 ));     match  msg {          Message::ChangeColor (Color::Rgb (r,g,b)) => {             println! ("rgb color, r = {},g= {},b = {}" ,r,g,b);           },          Message::ChangeColor (Color::Rgb (r,g,b)) => {             println! ("hsv color, h = {},s= {},v = {}" ,h,s,v);           },           _ => ()        };   } 
 
1 2 3 4 5 6 7 8 9 struct  Point  {    x: i32 ,     y: i32 ,   } fn  main () {    let  ((a,b),Point{x,y}) = ((1 ,2 ),Point{x: 3 ,y: 4 });         } 
 
忽略模式中的值 
可能使用下划线的场景
1 2 3 4 5 6 7 8 9 10 11 trait  A  {    fn  bar (x :i32 ,y: i32 );   } struct  B  {  } impl  A  for  B  {    fn  bar (_ :i32 ,y: i32 ) {         println! ("y = {}" ,y);       }   } 
 
1 2 3 4 5 6 7 fn  foo  (_ : i32 ,y: i32 ) {    println! ("y = {}" ,y);   } fn  main () {    foo (1 ,2 );   } 
 
1 2 3 4 5 6 7 8 fn  main () {    let  numbers  = (1 ,2 ,3 ,4 );     match  numbers {         (one,_,three,_) => {             println! ("one {},three {}" ,one,three);           },       }   } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 fn  main () {    let  _x  = 5 ;     let  _y  = 5 ;          let  s  = Some (String ::from ("hello" ));     if  let  Some (_c) = s {          println! ("found a string" );       }                         let  s  = Some (String ::from ("hello" ));     if  let  Some (_) = s {          println! ("found a string" );       }     println! ("s = {}" ,s);   } 
 
使用…匹配的过程中一定不能出现歧义 
如错误例子:
1 2 3 4 5 match  numbers {    (..,seconds,..) => {         println! ("second = {}" ,second);       }   } 
 
1 2 3 4 5 6 7 8 fn  main () {    let  numbers  = (1 ,2 ,3 ,4 ,5 ,6 ,7 );     match  numbers {         (first,..,last) => {             println! ("first {},last {}" ,first,last);           },       };   } 
 
匹配守卫提供额外的条件 
匹配守卫是一个指定于match分支模式之后,如果想要使用额外的if条件,必须满足这个分支 
这种方法不需要引进新的变量
 
1 2 3 4 5 6 7 8 fn  main () {    let  num  = Some (4 );     match  num {         Some (x) if  x < 5  => println! ("<5" ),         Some (x) => println! ("x {}" ,x),         None  => (),       };   } 
 
1 2 3 4 5 6 7 8 9 fn  main () {    let  num  = Some (4 );     let  y  = 10 ;     match  num {         Some (x) if  x == y => println! ("num ==y" ),         Some (x) => println! ("x {}" ,x),         None  => (),       };   } 
 
1 2 3 4 5 6 7 8 fn  main () {    let  x  = 4 ;     let  y  = false ;     match  x {         4 |5 |6  if  y => println! ("1" ),          _ => println! ("2" ),       };   } 
 
使用@运算符