letv=Vec2{x:3.0,y:6.0};letVec2{x,y}=v;// `x` is now 3.0, `y` is now `6.0`
还有这个:
12
letVec2{x,..}=v;// this throws away `v.y`
let模式可以用作if中的条件:
1 2 3 4 5 6 7 8 91011121314151617181920212223
structNumber{odd:bool,value:i32,}fnmain(){letone=Number{odd:true,value:1};lettwo=Number{odd:false,value:2};print_number(one);print_number(two);}fnprint_number(n:Number){ifletNumber{odd:true,value}=n{println!("Odd number: {}",value);}elseifletNumber{odd:false,value}=n{println!("Even number: {}",value);}}// this prints:// Odd number: 1// Even number: 2
match匹配也是一种模式,就像if let:
12345678
fnprint_number(n:Number){matchn{Number{odd:true,value}=>println!("Odd number: {}",value),Number{odd:false,value}=>println!("Even number: {}",value),}}// this prints the same as before
match必须是详尽的,至少需要一个分支来进行匹配
12345678
fnprint_number(n:Number){matchn{Number{value:1,..}=>println!("One"),Number{value:2,..}=>println!("Two"),Number{value,..}=>println!("{}",value),// if that last arm didn't exist, we would get a compile-time error}}
fnmain(){letminus_two=Number{odd:false,value:-2,};println!("positive? {}",minus_two.is_strictly_positive());// this prints "positive? false"}
默认情况下,变量绑定是不可变的,这意味着它的变量值不能改变:
12345678
fnmain(){letn=Number{odd:true,value:17,};n.odd=false;// error: cannot assign to `n.odd`,// as `n` is not declared to be mutable}
而且它们不能被赋值更改:
1 2 3 4 5 6 7 8 910
fnmain(){letn=Number{odd:true,value:17,};n=Number{odd:false,value:22,};// error: cannot assign twice to immutable variable `n`}
mut允许变量绑定可更改:
1234567
fnmain(){letmutn=Number{odd:true,value:17,}n.value=19;// all good}
trait是多种类型拥有的共同点:
123
traitSigned{fnis_strictly_negative(self)->bool;}
您可以实现:
为任意类型实现你自己定义的trait
为你的类型实现任意类型的trait
不允许为别人的类型实现别人的trait
这些被称为“孤立规则”(orphan rules)。
下面是自定义trait在自定义类型上的实现:
1 2 3 4 5 6 7 8 910
implSignedforNumber{fnis_strictly_negative(self)->bool{self.value<0}}fnmain(){letn=Number{odd:false,value:-44};println!("{}",n.is_strictly_negative());// prints "true"}
我们在外部类型(甚至是基本类型)上的实现的自定义trait:
1 2 3 4 5 6 7 8 910
implSignedfori32{fnis_strictly_negative(self)->bool{self<0}}fnmain(){letn:i32=-44;println!("{}",n.is_strictly_negative());// prints "true"}
自定义类型的外部trait:
1 2 3 4 5 6 7 8 9101112131415161718
// `Neg` 特性用于重载 `-`,// 一元减运算符。implstd::ops::NegforNumber{typeOutput=Number;fnneg(self)->Number{Number{value:-self.value,odd:self.odd,}}}fnmain(){letn=Number{odd:true,value:987};letm=-n;// this is only possible because we implemented `Neg`println!("{}",m.value);// prints "-987"}
fnmain(){leta:i32=15;letb=a;// `a` is copiedletc=a;// `a` is copied again}
这也是正常的:
123456789
fnprint_i32(x:i32){println!("x = {}",x);}fnmain(){leta:i32=15;print_i32(a);// `a` is copiedprint_i32(a);// `a` is copied again}
但Number类型没有实现Copy,所以下面的代码不起作用:
12345
fnmain(){letn=Number{odd:true,value:51};letm=n;// `n` is moved into `m`leto=n;// error: use of moved value: `n`}
这也不行:
123456789
fnprint_number(n:Number){println!("{} number {}",ifn.odd{"odd"}else{"even"},n.value);}fnmain(){letn=Number{odd:true,value:51};print_number(n);// `n` is movedprint_number(n);// error: use of moved value: `n`}
但如果采用不可变的引用print_number,就是可行的:
123456789
fnprint_number(n:&Number){println!("{} number {}",ifn.odd{"odd"}else{"even"},n.value);}fnmain(){letn=Number{odd:true,value:51};print_number(&n);// `n` is borrowed for the time of the callprint_number(&n);// `n` is borrowed again}
如果变量被声明为可变的,则函数参数使用可变引用也可以工作:
1 2 3 4 5 6 7 8 910111213
fninvert(n:&mutNumber){n.value=-n.value;}fnprint_number(n:&Number){println!("{} number {}",ifn.odd{"odd"}else{"even"},n.value);}fnmain(){// this time, `n` is mutableletmutn=Number{odd:true,value:51};print_number(&n);invert(&mutn);// `n is borrowed mutably - everything is explicitprint_number(&n);}
// note: `Copy` requires that `Clone` is implemented tooimplstd::clone::CloneforNumber{fnclone(&self)->Self{Self{..*self}}}implstd::marker::CopyforNumber{}
structPair<T>{a:T,b:T,}fnprint_type_name<T>(_val:&T){println!("{}",std::any::type_name::<T>());}fnmain(){letp1=Pair{a:3,b:9};letp2=Pair{a:true,b:false};print_type_name(&p1);// prints "Pair<i32>"print_type_name(&p2);// prints "Pair<bool>"}
标准库中的类型Vec(即分配在堆上的数组)就是泛型实现的:
12345678
fnmain(){letmutv1=Vec::new();v1.push(1);letmutv2=Vec::new();v2.push(false);print_type_name(&v1);// prints "Vec<i32>"print_type_name(&v2);// prints "Vec<bool>"}
fnmain(){leto1:Option<i32>=Some(128);o1.unwrap();// this is fineleto2:Option<i32>=None;o2.unwrap();// this panics!}// output: thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:378:21
enumOption<T>{None,Some(T),}impl<T>Option<T>{fnunwrap(self)->T{// enums variants can be used in patterns:matchself{Self::Some(t)=>t,Self::None=>panic!(".unwrap() called on a None option"),}}}useself::Option::{None,Some};fnmain(){leto1:Option<i32>=Some(128);o1.unwrap();// this is fineleto2:Option<i32>=None;o2.unwrap();// this panics!}// output: thread 'main' panicked at '.unwrap() called on a None option', src/main.rs:11:27
fnmain(){letmutx=42;letx_ref=&x;x=13;println!("x_ref = {}",x_ref);// error: cannot assign to `x` because it is borrowed}
当不可变地借用时,不能同时可变地的借用:
Tip:即不能对一个变量同时创建不可变和可变的引用
1234567
fnmain(){letmutx=42;letx_ref1=&x;letx_ref2=&mutx;// error: cannot borrow `x` as mutable because it is also borrowed as immutableprintln!("x_ref1 = {}",x_ref1);}
函数参数中的引用同样存在生命周期:
1234
fnprint(x:&i32){// `x` is borrowed (from the outside) for the// entire time this function is called.}