Rust精简核心笔记:第二波,语法精髓部分解锁

ops/2024/11/2 18:43:30/

前面介绍了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: 也欢迎大家评论和交流~ 更多文章也可关注微信公号:良技漫谈


http://www.ppmy.cn/ops/130492.html

相关文章

前端八股文第八篇

71. 请求参数如何防篡改 在前端开发中&#xff0c;通常需要发送请求到后端获取数据或执行操作。为了防止请求参数被篡改&#xff0c;可以采取以下措施&#xff1a; 使用 HTTPS 协议&#xff1a;使用 HTTPS 可以确保数据在传输过程中的加密和完整性验证&#xff0c;防止请求被中…

锁(Python)

简介 掩耳盗铃习惯了&#xff0c;今天整一点偏高级的&#xff0c;攻克一下我一直没拿下的自启动。 能修改自启动项&#xff0c;能在开机时启动&#xff0c;并在桌面创建&#xff08;基于注册表实现&#xff09;一个txt文件&#xff0c;向这个文件输入密码才能继续使用电脑&am…

开源办公软件 ONLYOFFICE 深入探索

文章目录 引言1. ONLYOFFICE 创建的背景1. 1 ONLYOFFICE 项目启动1. 2 ONLYOFFICE 的发展历程 2. 核心功能介绍2. 1 桌面编辑器2. 1. 1 文档2. 1. 2 表格2. 1. 3 幻灯片 2. 2 协作空间2. 3 文档编辑器 - 本地部署版 3. 技术介绍4. 安装5. 优势与挑战6. 个人体验7. 强大但不止于…

centos7 zabbix监控nginx的pv和uv和status_code

zabbix监控nginx的pv&#xff1a; pv)cat /var/log/nginx/access.log|awk {print $1}|wc -l;;zabbix-get验证&#xff1a; [rootbogon ~]# zabbix_get -s 192.168.253.231 -k pv_uv[pv] 100zabbix监控nginx的uv uv)cat /var/log/nginx/access.log|awk {print $1}|uniq -c | w…

web前端多媒体标签设置(图片,视频,音频)以及图片热区(usemap)的设置

多媒体标签运用 在HTML中有以下常见多媒体标签&#xff1a; <img> &#xff08;图像标签&#xff09; - 作用&#xff1a;用于在网页中嵌入图像。 - 示例&#xff1a; <img src"image.jpg" alt"这是一张图片"> 。其中 src 属性指定图像的…

硅谷甄选(8)spu

Spu模块 SPU(Standard Product Unit)&#xff1a;标准化产品单元。是商品信息聚合的最小单位&#xff0c;是一组可复用、易检索的标准化信息的集合&#xff0c;该集合描述了一个产品的特性。通俗点讲&#xff0c;属性值、特性相同的商品就可以称为一个SPU。 7.1 Spu模块的静态…

Java面试题库——SSM框架

一、Spring 1.为什么使用Spring&#xff1f; 方便解耦&#xff0c;便于开发&#xff1b; 支持aop切面编程&#xff1b; 声明式事务的支持&#xff1b; 方便程序的测试&#xff1b; 方便集成各种优秀的框架&#xff1b; 降低JavaEE API的使用难度。2.什么是AOP&#xff1f; A…

抖音短剧小程序上线:短视频平台的全新娱乐体验

抖音短剧小程序的开发是一个结合了创意与技术的过程&#xff0c;旨在通过简洁而富有吸引力的方式&#xff0c;向用户提供高质量的短剧内容。随着移动互联网的快速发展&#xff0c;短视频平台成为了人们日常生活中不可或缺的一部分&#xff0c;而短剧作为一种新兴的内容形式&…