【CS110L】Rust语言 Lecture3-4 笔记

文章目录

    • 第三讲 所有权:移动与借用&
          • 例1
          • 例2
          • 例3
      • 错误处理(开头)
          • 为什么空指针如此危险,我们能做什么以应对?— 引出Option
          • is_none()函数
          • unwrap_or()函数
          • 常见用法
    • 第四讲 代码实践:链表
          • Box
          • 节点和链表的定义
          • 节点和链表的构造函数
          • 判空 得到size
          • 插:take
          • Push Pop

第三讲 所有权:移动与借用&

为什么学习Rust?— 为了写出更安全的c/c++代码。Rust是人们对于c/c++缺点的回应,这个回应也有一些不足。

有些库会自己释放,给你指针,你不能用free,而是库提供的

一个包含了指向内存其他地方的指针的结构体的所有权传递问题在Rust和c/c++中都是有挑战的。Rust在编译时强迫你解决清除所有所有权的问题。

例1
// eg1.rs
fn main() {let s = String::from("hello");s.push_str(" world");
}

错,改为let **mut** s = String::from("hello");

例2
//eg2.rs
fn om_nom_nom(s: String) {println!("{}", s);// 释放s
}fn main() {let s = String::from("hello");om_nom_nom(s);// 到这里s的生命周期就结束了om_nom_nom(s);
}

错。相比以下c代码,free有四种放置方式,都可以通过编译。但只有一种是正确的。其余都会在运行时出现漏洞。

Rust起初感觉上是反直觉的,但是不容易错的。

//eg2.c
void om_nom_nom(char* s) {printf("%s\n", s);
}
int main() {char* s = strup("hello");om_nom_nom(s);om_nom_nom(s);free(s);
}

eg2.rs改法:

//eg2.rs
fn om_nom_nom(s: &String) {println!("{}", s);
}fn main() {let s = String::from("hello");om_nom_nom(&s); // 传引用om_nom_nom(&s);// s在这里释放
}
例3
// eg3.rs
fn main() {let s = String::from("hello");let s1 = &s;let s2 = &s;println!("{} {} {}", s, s1, s2);
}

对,s1 s2都是不可更改的副本

// eg3.rs
fn main() {let mut s = String::from("hello");let s1 = &mut s;let s2 = s;println!("{} {} {}", s, s1, s2);
}

错,rust的引用模型就是只有一个可改的,或者多个不可改的

// eg3.rs
fn main() {let mut s = String::from("hello");let s1 = &mut s;println!("{} {}", s, s1);
}

错, Rust 的借用规则不允许在同一作用域内同时存在可变引用和原始变量

// eg3.rs
fn main() {let mut s = String::from("hello");let s1 = &mut s;println!("{} {}", s1);println!("{} {}", s);
}

对,编译器看到了在使用s1时没有用过s,那就可以

// eg3.rs
fn main() {let mut s = String::from("hello");let s1 = &mut s;println!("{} {}", s);println!("{} {}", s1);
}

错误处理(开头)

Q:这段代码哪里有问题?
在这里插入图片描述
A:(本节课只讲第一点 —— 空指针)
在这里插入图片描述

为什么空指针如此危险,我们能做什么以应对?— 引出Option

None和值不会混在一起。

fn feeling_lucky() -> Option<String> {if get_random_num() > 10 {Some(String::from("lucky"))} else {None}
}
is_none()函数

if feeling_lucky().is_none()

unwrap_or()函数

let message = feeling_lucky().unwrap_or(String::from("No lucky"));

常见用法
match feeling_lucky() {Some(message) => {println!("Got message: {}", message);},None => {println!("No message returned.");}
}

第四讲 代码实践:链表

Box

在堆上分配,类似于c++的unique_ptr,优点:指针超出作用域后销毁,那块内存自动释放。

fn main() {let x: Box<u32> = Box::new(10);println!("{}", *x); // *x改为x,输出同样是10,因为自动解引用
}
// 输出:10
节点和链表的定义
struct LinkedList {head : Option<Box<Node>>, // ,size : usize,
}struct Node {value : u32,next : Option<Box<Node>>,
}

Q: next : Box<&Node> 行吗?

A:不行。我们在这里需要的是实际拥有下一个节点,不然考虑你从哪里借用。一个Box就是一个指针,指向heap上某处的拥有指针。只要Box存活(指在生命周期内),Node必须存活。

节点和链表的构造函数
impl Node {pub fn new(value: u32, next: Option<Box<Node>>) -> Node {Node {value: value, next: next}}
}impl LinkedList {pub fn new() -> LinkedList {LinkedList {head: None, size: 0}}
}
判空 得到size
pub fn get_size(&self) -> usize {self.size // (*self).size 也可。从习惯上讲,不需要的话不要显式解引用
}pub fn is_empty(&self) -> bool {self.size == 0
}
插:take
let mut x : Option<u32> = Some(5);
let x_ref : &mut Option<u32> = &mut x;
println!("{:?}", x_ref.take());
println!("{:?}", x);
// Some(5)
// None
Push Pop
pub fn push(&mut self, value: u32) {let tmp_node: Box<Node> = Box::new(Node::new(value, self.head.take()));self.head = Some(tmp_node); // 此Some对应head的类型是Optionself.size += 1;
}pub fn pop(&mut self) -> Option<u32> {let tmp_node: Box<Node> = self.head.take()?; //问号self.head = tmp_node.next;Some(tmp_node.value) // 此Some对应返回值的Option
}

关于?符号的解释:? 是错误传播操作符,它用于在遇到 Err 值时提前退出函数,并返回错误。当 ? 被用于 Option 类型时,如果 OptionNone,那么它会导致函数返回 None,并且提前退出函数。如果 OptionSome(value),那么 ? 会提取出 value 并继续执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

charls基于夜神模拟器抓取安卓7.0应用程序https请求

charls基于夜神模拟器抓取安卓7.0应用程序https请求 1、安装charls(安装步骤这里就不详细说了)2、下载证书(证书后缀名 xx.pem)3、使用git bash生成证书hash4、上传证书到安卓的系统证书目录下(夜神模拟器方案)5、验证抓包1、安装charls(安装步骤这里就不详细说了) 2、…

【Vue】2

1 Vue 生命周期 Vue生命周期&#xff1a;一个 Vue 实例从 创建 到 销毁 的整个过程 创建(create)阶段&#xff1a;组件实例化时&#xff0c;初始化数据、事件、计算属性等挂载(mount)阶段&#xff1a;将模板渲染并挂载到 DOM 上更新(update)阶段&#xff1a;当数据发生变化时…

数据中台建设(六)—— 数据开发-提取数据价值

数据开发-提取数据价值 数据开发涉及的产品能力主要包括三部分&#xff1a;离线开发、实时开发和算法开发。 离线开发主要包括离线数据的加工、发布、运维管理&#xff0c;以及数据分析、数据探索、在线查询和及时分析相关工作。实时开发主要涉及数据的实时接入和实时处理。算…

网络高级(学习)2024.9.10

目录 一、Modbus简介 1.起源 2.特点 3.应用场景 二、Modbus TCP协议 1.特点 2.协议格式 3.MBAP报文头 4.功能码 5.寄存器 &#xff08;1&#xff09;线圈寄存器&#xff0c;类比为开关量&#xff0c;每一个bit都对应一个信号的开关状态。 &#xff08;2&#xff09…

[项目实战]EOS多节点部署

文章总览&#xff1a;YuanDaiMa2048博客文章总览 EOS多节点部署 &#xff08;一&#xff09;环境设计&#xff08;二&#xff09;节点配置&#xff08;三&#xff09;区块信息同步&#xff08;四&#xff09;启动节点并验证同步EOS单节点的环境如何配置 &#xff08;一&#xf…

第十一周:机器学习

目录 摘要 Abstract 一、字符级的RNN进行名字分类 1、准备数据 2、构造神经网络 3、训练 4、评价结果 5、预测 二、字符级的RNN生成名字 1、准备数据 2、构造神经网络 3、训练 4、网络采样&#xff08;预测&#xff09; 三、batch normalization 1、 feature n…

Bootstrap 警告信息(Alerts)使用介绍

本章将讲解警告&#xff08;Alerts&#xff09;以及 Bootstrap 所提供的用于警告的 class。警告&#xff08;Alerts&#xff09;向用户提供了一种定义消息样式的方式。它们为典型的用户操作提供了上下文信息反馈。 您可以为警告框添加一个可选的关闭按钮。为了创建一个内联的可…

【工具箱】NAND NOR FLASH闪存

随着国内集成电路的发展&#xff0c;特别是存储芯片方面&#xff0c;关于NOR Flash&#xff0c;NAND Flash&#xff0c;SD NAND, eMMC, Raw NAND的资料越来越多了。这里我专门写了这篇文章&#xff1a;1&#xff0c;把常用的存储产品做了分类; 2&#xff0c;把这些产品的特点做…

[Postman]接口自动化测试入门

文章大多用作个人学习分享&#xff0c;如果大家觉得有不足或错漏的地方欢迎评论指出或补充 此文章将完整的走一遍一个web页面的接口测试流程 大致路径为&#xff1a; 创建集合->调用接口登录获取token->保存token->带着token去完成其他接口的自动化测试->断言-&g…

Kafka下载与安装教程(国产化生产环境无联网服务器部署实操)

请放心观看&#xff0c;已在正式环境部署验证&#xff0c;流程无问题&#xff01; 所用系统为国产化麒麟银河 aarch64系统&#xff0c;部署时间2024年9月份&#xff01; [rootecs-xxxxxx-xxx ~]# cat /etc/os-release NAME"Kylin Linux Advanced Server" VERSION&q…

MySQL 查询数据库的数据总量

需求&#xff1a;查看MySQL数据库的数据总量&#xff0c;以MB为单位展示数据库占用的磁盘空间 实践&#xff1a; 登录到MySQL数据库服务器。 选择你想要查看数据总量的数据库&#xff1a; USE shield;运行查询以获取数据库的总大小&#xff1a; SELECT table_schema AS Datab…

go语言后端开发学习(七)——如何在gin框架中集成限流中间件

一.什么是限流 限流又称为流量控制&#xff08;流控&#xff09;&#xff0c;通常是指限制到达系统的并发请求数。 我们生活中也会经常遇到限流的场景&#xff0c;比如&#xff1a;某景区限制每日进入景区的游客数量为8万人&#xff1b;沙河地铁站早高峰通过站外排队逐一放行的…

JAVA毕业设计170—基于Java+Springboot+vue3+小程序的房屋租赁小程序系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3小程序的房屋租赁小程序系统(源代码数据库)170 一、系统介绍 本项目前后端分离(可以改为ssm版本)&#xff0c;分为用户、房东、管理员三种角色 1、用户&am…

[000-002-01].第03节:Linux系统下Oracle的安装与使用

2.1.Docker安装Oracle 在CentOS7中使用Docker安装Oracle&#xff1a; 1.安装Docker,详细请参考&#xff1a;https://blog.csdn.net/weixin_43783284/article/details/1211403682.拉取镜像&#xff1a; docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g3.下载…

删除有序数组中的重复项(同向指针(快慢指针))

题目&#xff1a; 算法分析&#xff1a; 快慢指针从0出发若快慢指针不相同&#xff0c;快指针替换慢指针&#xff08;即慢指针后一位&#xff09;快指针每次都会增加题目求不重复的元素个数&#xff08;slow 为对应元素索引&#xff0c;故个数为slow1&#xff09; 算法图解…

如何通过编程工具提升工作效率

目录 常用编程工具介绍 工具效率对比 未来发展趋势 结论 在当今软件开发的高效环境中&#xff0c;工具的选择至关重要。无论是编写代码、调试&#xff0c;还是协作开发&#xff0c;合适的编程工具不仅能够简化开发流程&#xff0c;还可以有效地提高生产力。开发者在日常工作…

声波的波数,通常用k表示

声波的波数&#xff08;通常用 k 表示&#xff09;是描述声波空间变化的一个参数&#xff0c;它与声波的频率和介质中的传播速度有关。波数 k 是一个具体值&#xff0c;并且在均匀介质中它是固定的&#xff0c;计算公式如下&#xff1a; 均匀介质中的波数是一个具体值&#xff…

ESP8266+httpServer+GET+POST实现网页验证密码

1. 代码 #include "esp_http_server.h" #include "esp_log.h" #include "web_server.h"// 辅助宏&#xff0c;用于计算两个数中的较小值 #define MIN(a, b) ((a) < (b) ? (a) : (b))static const char *TAG "wifi web_server";c…

安卓BLE蓝牙通讯

蓝牙测试demo 简介   Android手机间通过蓝牙方式进行通信&#xff0c;有两种常见的方式&#xff0c;一种是socket方式&#xff08;传统蓝牙&#xff09;&#xff0c;另一种是通过GATT&#xff08;BLE蓝牙&#xff09;。与传统蓝牙相比&#xff0c;BLE 旨在大幅降低功耗。这样…

华为OD机试 - 推荐多样性(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…