西安网站建设制作需要哪些费用,大宗贸易平台,wordpress扫公众号二维码登录,百度网站搜索排名专栏简介#xff1a;本专栏作为Rust语言的入门级的文章#xff0c;目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言#xff0c;虽然历史没有C、和python历史悠远#xff0c;但是它的优点可以说是非常的多#xff0c;既继承了C运行速度#xff0c;还拥有了Java… 专栏简介本专栏作为Rust语言的入门级的文章目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言虽然历史没有C、和python历史悠远但是它的优点可以说是非常的多既继承了C运行速度还拥有了Java的内存管理就我个人来说还有一个优点就是集成化的编译工具cargo语句风格和C极其相似所以说我本人还是比较喜欢这个语言特此建立这个专栏作为学习的记录分享。 日常分享每天努力一点不为别的只是为了日后能够多一些选择选择舒心的日子选择自己喜欢的人 前面我们提到过Rust中没有了switch case这种模式控制语句但是喃除此之外却又多了另一种匹配规则那就是模式匹配。所以这节我们就来聊聊模式匹配这种匹配机制。
1、枚举
枚举其实在c中就有过定义二者相差不大关键字是enum枚举和结构体一样也是用来自定义的数据类型。
说到枚举可能有些同学还不是特别清楚枚举的意义在那里其实枚举他只是一个存放字段的一种容器吧在后面的代码中如果你需要多种字段但是你又不是特别明确具体需要哪些就把所有可能的字段放在其中需要什么就使用什么。
enum Error{typeError,lengthError,
} 例如上面的代码定义了一个Error的枚举类型这个时候Error就是一个数据类型。
1.1、枚举值
let oneError Error::typeError;let twoEroor Error::lengthError; 就如上面的代码我们定义了两个实例对象而他们的数值则是Error中的两个字段。
这里注意的是枚举的成员位于其标识符的命名空间中并使用两个冒号分开。
但是有人看到这里就会有疑惑这里的枚举类型中的字段都是没有具体值的那么我们如何将值与枚举成员关联
上一节讲解了结构体的概念这里我们就可以使用结构体来进行绑定 enum Error{typeError,lengthError,
}struct getError{oneError: Error,twoEroorderError: Error,address:String,
}
let amples getError{oneError: Error::typeError,twoEroorderError: Error::lengthError,address:String::from(Hello world),
};上面所时代码就是将枚举作为结构体的一部分除了上面的方法我们似乎还可以使用其他方法,例如将数据放进每一个枚举成员。
enum Error{typeError(String),lengthError(String),
}
let oneError Error::typeError(String::from(one error));
let twoEroor Error::lengthError(String::from(two Eroor error));
1.2、Option枚举
前面写的代码中对于枚举数据类型虽然将值通过结构体进行了绑定但是却没有具体的值只有通过将值放进枚举成员才能获得值。那么没有的值又是什么或者说又有什么作用
Rust语言和其他语言的一点不同就在于它没有空值也就是说不能赋予空值必须去实现。Rust 并没有空值不过它确实拥有一个可以编码存在或不存在概念的枚举。
enum OptionT{
None,
Some(T),
} OptionT 枚举是如此有用以至于它甚至被包含在了 prelude 之中你不需要将其显式引入作用域。另外它的成员也是如此可以不需要 Option:: 前缀来直接使用 Some 和 None。这里要注意Option枚举是含在标准库的不需要我们定义直接使用上面知识给出参考。
T 语法是一个我们还未讲到的 Rust 功能。它是一个泛型类型参数,后面遇到了我们再详细介绍。 let some_number Some(5);let some_char Some(e);let number:Optioni32None;
上面的三条语句变量some_number的类型是i32some_char的类型是char而number的类型是i32只是是一个空值。 对于OptionT这里的T可以是任何数据类型除了赋空值外一般来说不需要注明变量的数据类型除非是特殊需要Rust可以推断其变量的数据类型。如果是赋空值就必须注明变量的数据类型否则会报错。
不过这里需要注意的是OptionT标注的数据类型与相同的数据类型变量不能进行运算. let one_num:Optioni32some(20);let s:i3230;println!({},one_nums); error[E0425]: cannot find function some in this scope -- src/main.rs:45:27 | 45 | let one_num:Optioni32some(20); | ^^^^ help: a tuple variant with a similar name exists (notice the capitalization): Some error[E0369]: cannot add i32 to Optioni32 -- src/main.rs:47:24 | 47 | println!({},one_nums); | -------^- i32 | | | Optioni32 Some errors have detailed explanations: E0369, E0425. For more information about an error, try rustc --explain E0369. error: could not compile number due to 2 previous errors 当运行上述代码的时候就会出现这种报错,这是为什么喃?这是由于当我们使用OptionT 数据类型的时候就表明该数据可能为空,而我们使用i32(或其他数据类型)的时候,就已经表明改变两不可能为空值,所以才会出现报错,根本原因还是在与其数据类型被系统判定为两种数据类型. 换句话说在对 OptionT 进行运算之前必须将其转换为 T。通常这能帮助我们捕获到空值最常见的问题之一假设某值不为空但实际上为空的情况。
消除了错误地假设一个非空值的风险会让你对代码更加有信心。为了拥有一个可能为空的值你必须要显式的将其放入对应类型的 OptionT 中。接着当使用这个值时必须明确的处理值为空的情况。只要一个值不是 OptionT 类型你就 可以 安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策来限制空值的泛滥以增加 Rust 代码的安全性。
那么当有一个 OptionT 的值时如何从 Some 成员中取出 T 的值来使用它呢OptionT 枚举拥有大量用于各种情况的方法你可以查看它的文档。熟悉 OptionT 的方法将对你的 Rust 之旅非常有用。
总的来说为了使用 OptionT 值需要编写处理每个成员的代码。你想要一些代码只当拥有 Some(T) 值时运行允许这些代码使用其中的 T。也希望一些代码只在值为 None 时运行这些代码并没有一个可用的 T 值。match 表达式就是这么一个处理枚举的控制流结构它会根据枚举的成员运行不同的代码这些代码可以使用匹配到的值中的数据。
2、match控制流结构
我们前面说了在Rust语言中没有switch这种控制流语句但是它却推出了match这种强大的控制流运算符。在python语言中match是正则表达式中的匹配函数所以这里也可以理解为匹配函数。
先来看个例子
enum error_message{E0425,E0369,E2345,
}
fn get_error_message(message:error_message)-u32{match message{error_message::E0425 {println!(cannot find function some in this scope);return 0;}error_message::E0369{println!(cannot add i32 to Optioni32);return 1;}error_message::E2345{println!(could not compile number due to 2 previous errors);return 2;}}
}
fn main(){let mut errorget_error_message(error_message::E2345);println!({},error);get_error_message(error_message::E0425);
}
就如上面的代码先是定义了一个枚举数据类型然后定义了一个函数在函数中使用了match控制流。根据不同的参数值返回不同的值并打印出结果。
1.1、绑定值模式
匹配分支的另一个有用的功能是可以绑定匹配的模式的部分值。这也就是如何从枚举成员中提取值的。
/*
enum error_message{E0425,E0369,E2345,
}
fn get_error_message(message:error_message)-u32{match message{error_message::E0425 {println!(cannot find function some in this scope);return 0;}error_message::E0369{println!(cannot add i32 to Optioni32);return 1;}error_message::E2345{println!(could not compile number due to 2 previous errors);return 2;}}
}
fn main(){let mut errorget_error_message(error_message::E2345);println!({},error);get_error_message(error_message::E0425);
}
*/
#[derive(Debug)]
enum UsState{Alabama,Alaska,
}
enum Coin{Penny,Nickel,Dime,Quarter(UsState),
}
fn value_cents(coin:Coin) - usize {match coin{Coin::Penny {return 1;}Coin::Nickel {return 5;}Coin::Dime {return 10;}Coin::Quarter(state){println!(State quarter from {:#?},state);return 25;}}
}
fn main()
{let bUsState::Alaska;let cCoin::Quarter(b);value_cents(c);} 如果调用 value_in_cents(Coin::Quarter(UsState::Alaska))coin 将是 Coin::Quarter(UsState::Alaska)。当将值与每个分支相比较时没有分支会匹配直到遇到 Coin::Quarter(state)。这时state 绑定的将会是值 UsState::Alaska。接着就可以在 println! 表达式中使用这个绑定了像这样就可以获取 Coin 枚举的 Quarter 成员中内部的州的值。
1.2、匹配OptionT
我们在之前的部分中使用 OptionT 时是为了从 Some 中取出其内部的 T 值我们还可以像处理 Coin 枚举那样使用 match 处理 OptionT只不过这回比较的不再是硬币而是 OptionT 的成员但 match 表达式的工作方式保持不变。
例如
fn plus_amount(amount:Optioni32)-Optioni32
{match amount {None{println!(该值为空值);return None;}Some(i){println!(该值不是空值值为{},i);return Some(i);}}
}
fn main(){let fiveSome(5);let num1plus_amount(five);plus_amount(None);
}
1.3、通配模式和_占位符
其实除了枚举match控制流也可以用于其他形式比如
let num30;match num{10{println!(10);}11 println!(11),other println!(other),} 上面的代码中我们在最后使用了other这个变量这个变量覆盖了所有其他的可能值除了我们列出来的可能性other会包含所有的其他可能性所以other一定要放在最后否无法达到目的。
不过在这里因该有人发现了other会绑定match匹配的值这个我们将上面的程序更改一下就能的出这个结论
fn main(){let fiveSome(5);let num1plus_amount(five);plus_amount(None);let num30;match num{10{println!(10);}11 println!(11),other println!(other的值为:{},other),}
} other的值为:30 上面就是输出结果这说明other绑定到了match匹配的值上这样做的好处就是可以获得匹配值将其进行使用但是如果我们不需要使用那个值这样做就有点浪费所以Rust也推出了_占位符占位符只是表示可以匹配任意值而不能绑定到该值。
fn main(){let fiveSome(5);let num1plus_amount(five);plus_amount(None);let num30;match num{10{println!(10);}11 println!(11),_ println!(other),}
}3、if let间接控制流
Rust中的if let控制流说的简单点就相当于c中的if else语句对于一些简单的判别使用if let控制流语句将会简单很多。例如
fn main()
{let configSome(3u8);match config{Some(max)println!({},max),_(),}
}
上面面代码的意思是匹配config的值如果值是Some就将值绑定到max变量上然后输出否则就忽略。
除了上面这样的方式我们还可以使用其他的方式
fn main()
{let configSome(3u8);if let Some(max)config{println!({},max);}
}这样看来是不是就简单的多了所以说从某种角度来看if let语句确实简单了很多。
#[derive(Debug)]
enum UsState{Alabama,Alaska,
}
enum Coin{Penny,Nickel,Dime,Quarter(UsState),
}
fn main()
{let mut count0;let bUsState::Alaska;let coinCoin::Quarter(b);//以下两种方式都可以/*match coin{Coin::Quarter(state){println!(State quarter from {:#?},state);}_count1,}*/if let Coin::Quarter(state) coin{println!(State quarter from {:#?},state);}else{count1;}
}4、总结
现在我们涉及到了如何使用枚举来创建有一系列可列举值的自定义类型。我们也展示了标准库的 OptionT 类型是如何帮助你利用类型系统来避免出错的。当枚举值包含数据时你可以根据需要处理多少情况来选择使用 match 或 if let 来获取并使用这些值。
你的 Rust 程序现在能够使用结构体和枚举在自己的作用域内表现其内容了。在你的 API 中使用自定义类型保证了类型安全编译器会确保你的函数只会得到它期望的类型的值。
下一节我们学习模块系统。 文章转载自: http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn http://www.morning.qmfhh.cn.gov.cn.qmfhh.cn http://www.morning.smggx.cn.gov.cn.smggx.cn http://www.morning.lpsjs.com.gov.cn.lpsjs.com http://www.morning.yymlk.cn.gov.cn.yymlk.cn http://www.morning.sxfnf.cn.gov.cn.sxfnf.cn http://www.morning.ymwnc.cn.gov.cn.ymwnc.cn http://www.morning.bwhcl.cn.gov.cn.bwhcl.cn http://www.morning.mjtgt.cn.gov.cn.mjtgt.cn http://www.morning.xqkjp.cn.gov.cn.xqkjp.cn http://www.morning.ktsth.cn.gov.cn.ktsth.cn http://www.morning.dzgmj.cn.gov.cn.dzgmj.cn http://www.morning.rpwm.cn.gov.cn.rpwm.cn http://www.morning.fwcnx.cn.gov.cn.fwcnx.cn http://www.morning.lsxabc.com.gov.cn.lsxabc.com http://www.morning.kcnjz.cn.gov.cn.kcnjz.cn http://www.morning.wfmqc.cn.gov.cn.wfmqc.cn http://www.morning.nrwr.cn.gov.cn.nrwr.cn http://www.morning.fstdf.cn.gov.cn.fstdf.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.lqynj.cn.gov.cn.lqynj.cn http://www.morning.dkslm.cn.gov.cn.dkslm.cn http://www.morning.qmzwl.cn.gov.cn.qmzwl.cn http://www.morning.wdjcr.cn.gov.cn.wdjcr.cn http://www.morning.lmpfk.cn.gov.cn.lmpfk.cn http://www.morning.wjtxt.cn.gov.cn.wjtxt.cn http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn http://www.morning.kxryg.cn.gov.cn.kxryg.cn http://www.morning.xhsxj.cn.gov.cn.xhsxj.cn http://www.morning.wrbf.cn.gov.cn.wrbf.cn http://www.morning.rhmk.cn.gov.cn.rhmk.cn http://www.morning.jgcrr.cn.gov.cn.jgcrr.cn http://www.morning.rkqkb.cn.gov.cn.rkqkb.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.pbmkh.cn.gov.cn.pbmkh.cn http://www.morning.pcqxr.cn.gov.cn.pcqxr.cn http://www.morning.pqndg.cn.gov.cn.pqndg.cn http://www.morning.hmbxd.cn.gov.cn.hmbxd.cn http://www.morning.ydflc.cn.gov.cn.ydflc.cn http://www.morning.kflzy.cn.gov.cn.kflzy.cn http://www.morning.rkdnm.cn.gov.cn.rkdnm.cn http://www.morning.kxrld.cn.gov.cn.kxrld.cn http://www.morning.dpplr.cn.gov.cn.dpplr.cn http://www.morning.rknhd.cn.gov.cn.rknhd.cn http://www.morning.fthcn.cn.gov.cn.fthcn.cn http://www.morning.xcxj.cn.gov.cn.xcxj.cn http://www.morning.znknj.cn.gov.cn.znknj.cn http://www.morning.qnzpg.cn.gov.cn.qnzpg.cn http://www.morning.rhgtc.cn.gov.cn.rhgtc.cn http://www.morning.mksny.cn.gov.cn.mksny.cn http://www.morning.rhqr.cn.gov.cn.rhqr.cn http://www.morning.clnmf.cn.gov.cn.clnmf.cn http://www.morning.dqrpz.cn.gov.cn.dqrpz.cn http://www.morning.fhhry.cn.gov.cn.fhhry.cn http://www.morning.qbkw.cn.gov.cn.qbkw.cn http://www.morning.fmswb.cn.gov.cn.fmswb.cn http://www.morning.dzdtj.cn.gov.cn.dzdtj.cn http://www.morning.gktds.cn.gov.cn.gktds.cn http://www.morning.niukaji.com.gov.cn.niukaji.com http://www.morning.dbnrl.cn.gov.cn.dbnrl.cn http://www.morning.glbnc.cn.gov.cn.glbnc.cn http://www.morning.smdnl.cn.gov.cn.smdnl.cn http://www.morning.pffqh.cn.gov.cn.pffqh.cn http://www.morning.bqpgq.cn.gov.cn.bqpgq.cn http://www.morning.mmxnb.cn.gov.cn.mmxnb.cn http://www.morning.prplf.cn.gov.cn.prplf.cn http://www.morning.synkr.cn.gov.cn.synkr.cn http://www.morning.snkry.cn.gov.cn.snkry.cn http://www.morning.qghjc.cn.gov.cn.qghjc.cn http://www.morning.gjlxn.cn.gov.cn.gjlxn.cn http://www.morning.cwnqd.cn.gov.cn.cwnqd.cn http://www.morning.rtbj.cn.gov.cn.rtbj.cn http://www.morning.qrcsb.cn.gov.cn.qrcsb.cn http://www.morning.dyhlm.cn.gov.cn.dyhlm.cn http://www.morning.mtsgx.cn.gov.cn.mtsgx.cn http://www.morning.vvbsxm.cn.gov.cn.vvbsxm.cn http://www.morning.dqxph.cn.gov.cn.dqxph.cn http://www.morning.lyhry.cn.gov.cn.lyhry.cn http://www.morning.trsmb.cn.gov.cn.trsmb.cn http://www.morning.mgmyt.cn.gov.cn.mgmyt.cn