前面介绍了Rust精简比较第一波 Rust精简核心笔记:第一波,深入浅出语法精华-CSDN博客 把第二波整理如下,通过三波会把全部Rust核心、实用、最简练的语法整理出来,最高效掌握Rust。
Rust精简笔记(二)
-
Rust核心笔记第二波总结整理,第七部分: match控制流结构、第八部分: 泛型&Trait&生命周期,第九部分: 集合,第八部分也是rust语言精髓特性
-
参考The Rust Programming Language & Rust in Action
七.match控制流结构
-
前面第三部分流程控制里简单说明了match使用,结合enum来看看match的更多使用场景总结
-
基础匹配语法:
let number = 2;match number {1 | 2 => println!("1 or 2"), // 匹配到某一个3..=5 => println!("3到5"), // 通过 ..= 匹配值的范围_ => println!("invalid"), //未匹配到 _}
match 解构结构体:
struct Point {x: i32,y: i32,
}fn main() {let p = Point { x: 0, y: 7 };let Point { x: a, y: b } = p;assert_eq!(0, a);assert_eq!(7, b);
}
解构枚举:
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!("The Quit variant has no data to destructure.")}Message::Move { x, y } => {println!("Move in the x direction {} and in the y direction {}",x, y);}Message::Write(text) => println!("Text message: {}", text),Message::ChangeColor(r, g, b) => println!("Change the color to red {}, green {}, and blue {}",r, g, b),}
}
//打印结果到change the color....
解构嵌套的结构体和枚举:
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!("Change the color to red {}, green {}, and blue {}",r, g, b),Message::ChangeColor(Color::Hsv(h, s, v)) => println!("Change the color to hue {}, saturation {}, and value {}",h, s, v),_ => (),}
}
用 .. 忽略剩余值:
//通过使用 .. 来忽略 Point 中除 x 以外的字段
fn main() {struct Point {x: i32,y: i32,z: i32,}let origin = Point { x: 0, y: 0, z: 0 };match origin {Point { x, .. } => println!("x is {}", x),}
}
Match guards:
-
• 匹配守卫(match guard)是一个指定于 match 分支模式之后的额外 if 条件,它也必须被满足才能选择此分支
fn main() {let num = Some(4);match num {Some(x) if x < 5 => println!("less than five: {}", x),Some(x) => println!("{}", x),None => (),}
}
@绑定:
-
运算符@,允许我们在创建一个存放值的变量的同时,测试其值是否匹配模式。即@ 可以在一个模式中同时测试和保存变量值。
fn main() {enum Message {Hello { id: i32 },}let msg = Message::Hello { id: 5 };match msg {Message::Hello {id: id_variable @ 3..=7, //使用id_variable变量配合@,以便此分支相关联的代码可以使用它} => println!("Found an id in range: {}", id_variable),Message::Hello { id: 10..=12 } => {println!("Found an id in another range")}Message::Hello { id } => println!("Found some other id: {}", id),}
}
八,泛型、Trait、生命周期
泛型:
-
函数定义中使用泛型
fn largest<T>(list: &[T]) -> T {
}
//函数 largest 有泛型类型 T。它有个参数 list,其类型是元素为 T 的 slice。largest 函数的返回值类型也是 T
//类型参数声明位于函数名称与参数列表中间的尖括号 <>
-
结构体定义中的泛型
struct Point<T> {x: T,y: T,
}fn main() {let integer = Point { x: 5, y: 10 };let float = Point { x: 1.0, y: 4.0 };
}
-
枚举定义中的泛型
enum Option<T> {Some(T),None,
}enum Result<T, E> {Ok(T),Err(E),
}
-
方法定义中的泛型
struct Point<T> {x: T,y: T,
}impl<T> Point<T> {fn x(&self) -> &T {&self.x}
}fn main() {let p = Point { x: 5, y: 10 };println!("p.x = {}", p.x());
}
Trait:
-
通过 trait 以一种抽象的方式定义共享的行为,trait 类似于其他语言中的接口,但也不完全一样.
//定义 trait Summary ,定义summarize调取->summarize_author默认方法,达到调用默认行为,区分开实现trait的的定义
pub trait Summary {fn summarize_author(&self) -> String;fn summarize(&self) -> String {format!("(Read more from {}...)", self.summarize_author())}
}pub struct Tweet {pub username: String,pub content: String,pub reply: bool,pub retweet: bool,
}
//实现 trait Summary
impl Summary for Tweet {fn summarize_author(&self) -> String {format!("@{}", self.username)}
}fn main() {let tweet = Tweet {username: String::from("horse_ebooks"),content: String::from("of course, as you probably already know, people"),reply: false,retweet: false,};println!("1 new tweet: {}", tweet.summarize());
}
-
trait 作为参数:
// 方法接收是实现了 trait Summary的类型
pub fn notify(item: &impl Summary) {println!("Breaking news! {}", item.summarize());
}
-
Trait Bound: impl Trait 适用于短小的例子。trait bound 则适用于更复杂的场景,trait bound 与泛型参数声明在一起,位于尖括号中的冒号后面。
//使用相同类型的trait可以转换成下边的更简单写法
pub fn notify(item1: &impl Summary, item2: &impl Summary) {}// trait Bound的写法
pub fn notify<T: Summary>(item1: &T, item2: &T) {}
-
通过
+
指定多个 trait bound:
pub fn notify<T: Summary + Display>(item: &T) {}
-
通过
where
简化 trait bound:每个泛型有其自己的 trait bound,所以有多个泛型参数的函数在名称和参数列表之间会有很长的 trait bound 信息,这使得函数签名难以阅读
fn some_function<T, U>(t: &T, u: &U) -> i32where T: Display + Clone,U: Clone + Debug
{
}
声明周期:
-
Rust 中的每一个引用都有其 生命周期(lifetime),也就是引用保持有效的作用域,Rust 编译器有一个借用检查器(borrow checker)它比较作用域来确保所有的借用都是有效的
-
函数签名中的生命周期注解:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {if x.len() > y.len() {x} else {y}
}
fn main() {let string1 = String::from("abcd");let string2 = "xyz";let result = longest(string1.as_str(), string2);println!("The longest string is {}", result);
}
-
参数声明周期使用方法,或者靠编译器提示添加。
&i32 // 引用, 没有生命周期参数的 i32 的引用
&'a i32 // 带有显式生命周期的引用 ,一个有叫做 'a 的生命周期参数的 i32 的引用
&'a mut i32 // 带有显式生命周期的可变引用 一个生命周期也是 'a 的 i32 的可变引用
-
结构体定义中的生命周期注解:
struct ImportantExcerpt<'a> {part: &'a str,
}
fn main() {let novel = String::from("Call me Ishmael. Some years ago...");let first_sentence = novel.split('.').next().expect("Could not find a '.'");let i = ImportantExcerpt {part: first_sentence,};
}
-
静态生命周期:
-
生命周期能够存活于整个程序期间。所有的字符串字面值都拥有 'static 生命周期
let s: &'static str = "I have a static lifetime.";
九,集合:
vector:
-
类型是 Vec
在内存中彼此相邻地排列所有的值, vector 只能储存相同类型的值
// Vec::new 创建let v: Vec<i32> = Vec::new();v.push(2);v.push(4);let x = v.pop();
-
初始值来创建一个 Vec :
let v = vec![1, 2, 3];
-
读取 vector 的元素: 使用 &[index] 返回一个引用, 或者使用 get 方法以索引作为参数来返回一个 Option<&T>。
fn main() {let v = vec![1, 2, 3, 4, 5];let third: &i32 = &v[2];println!("The third element is {}", third);match v.get(2) {Some(third) => println!("The third element is {}", third),None => println!("There is no third element."),}
}
-
使用枚举来储存多种类型: 创建一个储存枚举值的 vector,这样最终就能够通过vector存储实际是不同类型的值了
fn main() {enum SpreadsheetCell {Int(i32),Float(f64),Text(String),}let row = vec![SpreadsheetCell::Int(3),SpreadsheetCell::Text(String::from("blue")),SpreadsheetCell::Float(10.12),];
}
HashMap
let mut scores = HashMap::new();scores.insert(String::from("Blue"), 10); //插入//只在键没有对应值时插入scores.entry(String::from("Yellow")).or_insert(50);scores.entry(String::from("Blue")).or_insert(50);println!("{:?}", scores);
第二波先介绍到这里,后边会把第三波的整理出来,这些精简的笔记也可以做为日常学习rust回顾、知识点速查等。
PS: 也欢迎大家评论和交流~ 更多文章也可关注微信公号:良技漫谈