// 获得一个 `i32` 类型的引用。`&` 表示获取一个引用。letreference=&4;// 为了避免 `&` 的使用,需要在匹配前解引用。match*reference{val=>println!("Got a value via dereferencing: {:?}",val),}
如果match是对一个引用进行模式匹配的化,可以使用值的方式、ref的方式来,&的方式来进行匹配
1234567
letreference=&4;matchreference{// val => println!("xxxx"),// ref val => println!("xxxxx"),&val=>println!("Got a value via destructuring: {:?}",val),}
模式匹配的时候可以通过..来忽略某些变量
match匹配的时候,还可以额外添加guard来过滤
12345678
letpair=(2,-2);println!("Tell me about {:?}",pair);matchpair{(x,y)ifx==y=>println!("These are twins"),(x,y)ifx+y==0=>println!("Antimatter, kaboom!"),(x,_)ifx%2==1=>println!("The first one is odd"),_=>println!("No correlation..."),}
match匹配的时候,如果匹配的是一系列的值时可以通过@来绑定匹配到的一系列值
1234567
letage: u32=15;matchage{0=>println!("I'm not born yet I guess"),n@1...12=>println!("I'm a child of age {:?}",n),n@13...19=>println!("I'm a teen of age {:?}",n),n=>println!("I'm an old person of age {:?}",n),}
When data is immutably borrowed, it also freezes.
Frozen data can't be modified via the original object until all references to it go out of scope:
Data can be immutably borrowed any number of times, but while immutably borrowed,
the original data can't be mutably borrowed. On the other hand, only one mutable borrow is allowed at a time.
The original data can be borrowed again only after the mutable reference goes out of scope
1 2 3 4 5 6 7 8 91011121314151617
fnmain(){letmut_mutable_integer=7i32;{// Borrow `_mutable_integer`let_large_integer=&_mutable_integer;// Error! `_mutable_integer` is frozen in this scope_mutable_integer=50;// FIXME ^ Comment out this line// `_large_integer` goes out of scope}// Ok! `_mutable_integer` is not frozen in this scope_mutable_integer=3;}
Function with lifetimes
function signatures with lifetimes have a few constraints:
any reference must have an annotated lifetime.
any reference being returned must have the same lifetime as an input or be static.
Each elided lifetime in input position becomes a distinct lifetime parameter.
If there is exactly one input lifetime position (elided or not), that lifetime is assigned to all elided output lifetimes.
If there are multiple input lifetime positions, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.
Otherwise, it is an error to elide an output lifetime.
impl<T>Option<T>{fnunwrap(self)-> T{matchself{Option::Some(val)=>val,Option::None=>panic!("called `Option::unwrap()` on a `None` value"),}}}usestd::env;fnmain(){letmutargv=env::args();letarg: String=argv.nth(1).unwrap();letn: i32=arg.parse().unwrap();println!("{}",2*n);}
fnmap<F,T,A>(option: Option<T>,f: F)-> Option<A>whereF: FnOnce(T)-> A{matchoption{None=>None,Some(value)=>Some(f(value)),}}// Searches `haystack` for the Unicode character `needle`. If one is found, the// byte offset of the character is returned. Otherwise, `None` is returned.fnfind(haystack: &str,needle: char)-> Option<usize>{for(offset,c)inhaystack.char_indices(){ifc==needle{returnSome(offset);}}None}fnmain(){letm=find("findstring",'d');println!("size: {}",m.map(|x|(x+100).to_string()+"oo").unwrap());}
fnand_then<F,T,A>(option: Option<T>,f: F)-> Option<A>whereF: FnOnce(T)-> Option<A>{matchoption{None=>None,Some(value)=>f(value),}}// Searches `haystack` for the Unicode character `needle`. If one is found, the// byte offset of the character is returned. Otherwise, `None` is returned.fnfind(haystack: &str,needle: char)-> Option<usize>{for(offset,c)inhaystack.char_indices(){ifc==needle{returnSome(offset);}}None}fnmain(){letm=find("findstring",'d');println!("size: {}",m.and_then(|x|Some(x.to_string()+"test")).unwrap());}
fnok_or<T,E>(option: Option<T>,err: E)-> Result<T,E>{matchoption{Some(val)=>Ok(val),None=>Err(err),}}usestd::env;fndouble_arg(mutargv: env::Args)-> Result<i32,String>{argv.nth(1).ok_or("Please give at least one argument".to_owned()).and_then(|arg|arg.parse::<i32>().map_err(|err|err.to_string()))}fnmain(){matchdouble_arg(env::args()){Ok(n)=>println!("{}",n),Err(err)=>println!("Error: {}",err),}}
map_err Maps a Result<T, E> to Result<T, F>,如果是Ok就原封不动返回,否则就将error值传递给fucntion,返回另一种类型,最后将结果包装成Result
usestd::fmt::{Debug,Display};traitError: Debug+Display{/// A short description of the error.fndescription(&self)-> &str;/// The lower level cause of this error, if any.fncause(&self)-> Option<&Error>{None}}
usestd::mem;usestd::ptr;// Only declare the array. This safely leaves it// uninitialized in a way that Rust will track for us.// However we can't initialize it element-by-element// safely, and we can't use the `[value; 1000]`// constructor because it only works with `Copy` data.letmutdata: [Vec<u32>;1000];unsafe{data=mem::uninitialized();forelemin&mutdata[..]{ptr::write(elem,Vec::new());}}println!("{:?}",&data[0]);
// `print_refs` takes two references to `i32` which have different// lifetimes `'a` and `'b`. These two lifetimes must both be at// least as long as the function `print_refs`.fnprint_refs<'a,'b>(x: &'ai32,y: &'bi32){println!("x is {} and y is {}",x,y);}// A function which takes no arguments, but has a lifetime parameter `'a`.fnfailed_borrow<'a>(){let_x=12;// ERROR: `_x` does not live long enough// _x的生命周期显然没有'static长//let y: &'a i32 = &_x;// Attempting to use the lifetime `'a` as an explicit type annotation// inside the function will fail because the lifetime of `&_x` is shorter// than that of `y`. A short lifetime cannot be coerced into a longer one.}fnmain(){// Create variables to be borrowed below.let(four,nine)=(4,9);// Borrows (`&`) of both variables are passed into the function.print_refs(&four,&nine);// Any input which is borrowed must outlive the borrower.// In other words, the lifetime of `four` and `nine` must// be longer than that of `print_refs`.// 生命周期默认是'staticfailed_borrow();// `failed_borrow` contains no references to force `'a` to be// longer than the lifetime of the function, but `'a` is longer.// Because the lifetime is never constrained, it defaults to `'static`.}
当数据被不可变借用的时候,那么将无法通过原来可变的变量进行数据的修改
1 2 3 4 5 6 7 8 9101112131415
fnmain(){letmut_mutable_integer=7i32;{// Borrow `_mutable_integer`// 做了不可变的借用let_large_integer=&_mutable_integer;// Error! `_mutable_integer` is frozen in this scope// 导致原来的的无法修改_mutable_integer=50;// FIXME ^ Comment out this line// `_large_integer` goes out of scope}// Ok! `_mutable_integer` is not frozen in this scope_mutable_integer=3;}
当数据被move的时候可以改变其可变性
1 2 3 4 5 6 7 8 9101112131415161718
fnmain(){letimmutable_box=Box::new(5u32);println!("immutable_box contains {}",immutable_box);// Mutability error//*immutable_box = 4;// *Move* the box, changing the ownership (and mutability)letmutmutable_box=immutable_box;println!("mutable_box contains {}",mutable_box);// Modify the contents of the box*mutable_box=4;println!("mutable_box now contains {}",mutable_box);}
error handle
cargo
Dev-dependencies are not used when compiling a package for building, but are used for compiling tests, examples, and benchmarks.
[dev-dependencies]
tempdir = "0.3"
attribute
This RFC introduces the #[non_exhaustive] attribute for enums and structs, which indicates that more variants/fields may be added to an enum/struct in the future.
Adding this hint to enums will force downstream crates to add a wildcard arm to match statements, ensuring that adding new variants is not a breaking change.
Adding this hint to structs or enum variants will prevent downstream crates from constructing or exhaustively matching, to ensure that adding new fields is not a breaking change.