【Rust练习】21.动态数组 Vector

练习题来自:https://practice-zh.course.rs/collections/vector.html

1


fn main() {let arr: [u8; 3] = [1, 2, 3];let v = Vec::from(arr);is_vec(v);let v = vec![1, 2, 3];is_vec(v);// vec!(..) 和 vec![..] 是同样的宏,宏可以使用 []、()、{}三种形式,因此...let v = vec!(1, 2, 3);is_vec(v);// ...在下面的代码中, v 是 Vec<[u8; 3]> , 而不是 Vec<u8>// 使用 Vec::new 和 `for` 来重写下面这段代码let v1 = vec!(arr);is_vec(v1);assert_eq!(v, v1);println!("Success!")
}fn is_vec(v: Vec<u8>) {}

我真不觉得作者的意思是这么写,但是我只能这么写了。。

    let v1 = Vec::new();let v = vec!{1, 2, 3};is_vec(v1);let mut v1:Vec<u8> = Vec::new();for e in &v{v1.push(*e);}assert_eq!(v, v1);println!("Success!")

另外吐槽Rust这个for循环,只有for each格式的,没有三段式的。虽然for each也能转成三段式吧。

C++使用vector代表定长数组,据说是一个失误。但是Rust也这么搞,我倾向于是吸引从C++转来的程序员。这个宏定义需要加感叹号,感觉有点卡手。

2


// 填空
fn main() {let mut v1 = Vec::from([1, 2, 4]);v1.pop();v1.push(3);let mut v2 = Vec::new();v2.__;assert_eq!(v1, v2);println!("Success!")
}

extend可以将vector拼接到vector的后面,如果C++实现类似的功能,需要用insert,还需要指定迭代器,就这点来说Rust还不错。

    vector<int> v1(a1,a1+3);vector<int> v2(a2,a2+3);v1.insert(v1.end(),v2.begin(),v2.end());

3


// 填空
fn main() {// array -> Vec// impl From<[T; N]> for Veclet arr = [1, 2, 3];let v1 = __(arr);let v2: Vec<i32> = arr.__();assert_eq!(v1, v2);// String -> Vec// impl From<String> for Veclet s = "hello".to_string();let v1: Vec<u8> = s.__();let s = "hello".to_string();let v2 = s.into_bytes();assert_eq!(v1, v2);// impl<'_> From<&'_ str> for Veclet s = "hello";let v3 = Vec::__(s);assert_eq!(v2, v3);// 迭代器 Iterators 可以通过 collect 变成 Veclet v4: Vec<i32> = [0; 10].into_iter().collect();assert_eq!(v4, vec![0; 10]);println!("Success!")}

这里其实和Vec没多大关系,更多是在讲FromInfo特征。

fn main() {// array -> Vec// impl From<[T; N]> for Veclet arr = [1, 2, 3];let v1 = Vec::from(arr);let v2: Vec<i32> = arr.into();assert_eq!(v1, v2);// String -> Vec// impl From<String> for Veclet s = "hello".to_string();let v1: Vec<u8> = s.into();let s = "hello".to_string();let v2 = s.into_bytes();assert_eq!(v1, v2);// impl<'_> From<&'_ str> for Veclet s = "hello";let v3 = Vec::from(s);assert_eq!(v2, v3);// 迭代器 Iterators 可以通过 collect 变成 Veclet v4: Vec<i32> = [0; 10].into_iter().collect();assert_eq!(v4, vec![0; 10]);println!("Success!")}

这两个特征的定义如下,用法都在上面了:

pub trait From<T>: Sized {// Required methodfn from(value: T) -> Self;
}pub trait Into<T>: Sized {// Required methodfn into(self) -> T;
}

需要注意的有几点:

  1. 绝大多数标准库都实现了这两个特征
  2. 实现了From会自动实现Into
  3. 由于into的结果可能有多种类型,你需要手动指定类型。
  4. Rust为FromInto给出了一些原则,不过就目前的学习阶段来看,这些原则不是特别重要(比如转换必须是无损的)

4


// 修复错误并实现缺失的代码
fn main() {let mut v = Vec::from([1, 2, 3]);for i in 0..5 {println!("{:?}", v[i])}for i in 0..5 {// 实现这里的代码...}assert_eq!(v, vec![2, 3, 4, 5, 6]);println!("Success!")
}

有时候我觉得这题目挺cd的。

    for i in 0..5 {if let Some(x) = v.get(i){v[i] = x+1;}else {//i=3,4v.push(i+2);}}

5


// 修复错误
fn main() {let mut v = vec![1, 2, 3];let slice1 = &v[..];// 越界访问将导致 panic.// 修改时必须使用 `v.len`let slice2 = &v[0..4];assert_eq!(slice1, slice2);// 切片是只读的// 注意:切片和 `&Vec` 是不同的类型,后者仅仅是 `Vec` 的引用,并可以通过解引用直接获取 `Vec`let vec_ref: &mut Vec<i32> = &mut v;(*vec_ref).push(4);let slice3 = &mut v[0..3];slice3.push(4);assert_eq!(slice3, &[1, 2, 3, 4]);println!("Success!")
}

答案

fn main() {let mut v = vec![1, 2, 3];let slice1 = &v[..];// 越界访问将导致 panic.// 修改时必须使用 `v.len`let slice2 = &v[0..v.len()];assert_eq!(slice1, slice2);// 切片是只读的// 注意:切片和 `&Vec` 是不同的类型,后者仅仅是 `Vec` 的引用,并可以通过解引用直接获取 `Vec`let vec_ref: &mut Vec<i32> = &mut v;(*vec_ref).push(4);let slice3 = &mut v[..];assert_eq!(slice3, &[1, 2, 3, 4]);println!("Success!")
}

你要是用VS Code之类的IDE就能看出来,Vec切片的本质就是数组。当然,C++的vector是没有切片这个功能的。

6

// 修复错误
fn main() {let mut vec = Vec::with_capacity(10);assert_eq!(vec.len(), __);assert_eq!(vec.capacity(), 10);// 由于提前设置了足够的容量,这里的循环不会造成任何内存分配...for i in 0..10 {vec.push(i);}assert_eq!(vec.len(), __);assert_eq!(vec.capacity(), __);// ...但是下面的代码会造成新的内存分配vec.push(11);assert_eq!(vec.len(), 11);assert!(vec.capacity() >= 11);// 填写一个合适的值,在 `for` 循环运行的过程中,不会造成任何内存分配let mut vec = Vec::with_capacity(__);for i in 0..100 {vec.push(i);}assert_eq!(vec.len(), __);assert_eq!(vec.capacity(), __);println!("Success!")
}

如果你用C++,那你对这里的sizecapacity的区别应该不会陌生。写算法题时出于性能的考虑,往往需要提前分配足够的空间。

fn main() {let mut vec = Vec::with_capacity(10);assert_eq!(vec.len(), 0);assert_eq!(vec.capacity(), 10);// 由于提前设置了足够的容量,这里的循环不会造成任何内存分配...for i in 0..10 {vec.push(i);}assert_eq!(vec.len(), 10);assert_eq!(vec.capacity(), 10);// ...但是下面的代码会造成新的内存分配vec.push(11);assert_eq!(vec.len(), 11);assert!(vec.capacity() >= 11);// 填写一个合适的值,在 `for` 循环运行的过程中,不会造成任何内存分配let mut vec = Vec::with_capacity(100);for i in 0..100 {vec.push(i);}assert_eq!(vec.len(), 100);assert_eq!(vec.capacity(), 100);println!("Success!")
}

7

#[derive(Debug)]
enum IpAddr {V4(String),V6(String),
}
fn main() {// 填空let v : Vec<IpAddr>= __;// 枚举的比较需要派生 PartialEq 特征assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));assert_eq!(v[1], IpAddr::V6("::1".to_string()));println!("Success!")
}

又是为这种神奇的枚举惊叹的一次,这还能叫枚举吗?

#[derive(Debug, PartialEq)]
enum IpAddr {V4(String),V6(String),
}
fn main() {// 填空let v : Vec<IpAddr>= vec!{IpAddr::V4("127.0.0.1".to_string()), IpAddr::V6("::1".to_string())};// 枚举的比较需要派生 PartialEq 特征assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));assert_eq!(v[1], IpAddr::V6("::1".to_string()));println!("Success!")
}

8

trait IpAddr {fn display(&self);
}struct V4(String);
impl IpAddr for V4 {fn display(&self) {println!("ipv4: {:?}",self.0)}
}
struct V6(String);
impl IpAddr for V6 {fn display(&self) {println!("ipv6: {:?}",self.0)}
}fn main() {// 填空let v: __= vec![Box::new(V4("127.0.0.1".to_string())),Box::new(V6("::1".to_string())),];for ip in v {ip.display();}
}

C++的vector用法也是差不多的,父类作为声明,子类填入。

fn main() {// 填空let v:Vec<Box<dyn IpAddr>>= vec![Box::new(V4("127.0.0.1".to_string())),Box::new(V6("::1".to_string())),];for ip in v {ip.display();}
}

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

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

相关文章

Ollama的安装以及大模型下载教程

简介 Ollama是一个开源的大型语言模型服务工具&#xff0c;它帮助用户快速在本地运行大模型。通过简单的安装指令&#xff0c;用户可以执行一条命令就在本地运行开源大型语言模型&#xff0c; Ollama极大地简化了在Docker容器内部署和管理LLM的过程&#xff0c;使得用户能够快…

算法演练----24点游戏

给定4个整数&#xff0c;数字范围在1~13之间任意使用-*/&#xff08;&#xff09;&#xff0c;构造出一个表达式&#xff0c;使得最终结果为24&#xff0c; 方法一 算法分析&#xff1a;加括号和取出重复表达式 # 导入精确除法模块&#xff0c;使得在Python2中除法运算的行为更…

YUM 的使用

YUM 是一个用于 Fedora 和 Red Hat 以及 CentOS 操作系统的前端软件包管理器&#xff0c;它可以自动处理依赖关系并一次性安装所有必需的软件包。 镜像站点选择 1. 备份原有的镜像源配置文件 系统默认的 yum 镜像源配置文件存储在 /etc/yum.repos.d/ 目录下&#xff0c;可以…

第三十六章 Vue之路由重定向/404页面设置/路径模式设置

目录 一、路由重定向 1.1. 使用方式 1.2. 完整代码 1.2.1. main.js 1.2.2. App.vue 1.2.3. index.js 1.2.4. Search.vue 1.2.5. Home.vue 1.3. 运行效果 二、设定404错误页面 2.1. 使用方式 2.2. 完整代码 2.2.1. index.js 2.2.2. NotFound.vue 2.2.3. 运行效…

鸿蒙进阶篇-属性动画-animateTo转场动画

大家好啊&#xff0c;这里是鸿蒙开天组&#xff0c;今天我们来学习属性动画-animateTo&转场动画&#xff0c;咱们先来学习属性动画-animateTo 属性动画-animateTo 属性动画 animation是作为属性使用&#xff0c;而animateTo显示动画是一个系统的内置函数&#xff0c;可以…

[CKS] K8S ServiceAccount Set Up

最近准备花一周的时间准备CKS考试&#xff0c;在准备考试中发现有一个题目关于Rolebinding的题目。 ​ 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS] K8S Netwo…

Autosar CP DDS规范导读

Autosar CP DDS 主要用途 数据通信 中间件协议&#xff1a;作为一种中间件协议&#xff0c;DDS实现了应用程序之间的高效数据通信&#xff0c;能够在不同的软件组件和ECU之间传输数据&#xff0c;确保数据的实时性和可靠性。跨平台通信&#xff1a;支持在AUTOSAR CP平台上的不同…

wafw00f源码详细解析

声明 本人菜鸟一枚&#xff0c;为了完成作业&#xff0c;发现网上所有的关于wafw00f的源码解析都是这抄那那抄这的&#xff0c;没有新东西&#xff0c;所以这里给出一个详细的源码解析&#xff0c;可能有错误&#xff0c;如果有大佬发现错误&#xff0c;可以在评论区平和的指出…

字节、快手、Vidu“打野”升级,AI视频小步快跑

文&#xff5c;白 鸽 编&#xff5c;王一粟 继9月份版本更新之后&#xff0c;光锥智能从生数科技联合创始人兼CEO唐家渝朋友圈获悉&#xff0c;Vidu大模型将于本周再次进行版本升级&#xff0c;Vidu-1.5版本即将上线。 此版本更新方向仍是重点延伸大模型的泛化能力和主体…

LeetCode【0036】有效的数独

本文目录 1 中文题目2 求解方法&#xff1a;python内置函数set2.1 方法思路2.2 Python代码2.3 复杂度分析 3 题目总结 1 中文题目 请根据以下规则判断一个 9 x 9 的数独是否有效。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线…

STM32 GPIO 配置

GPIO 八种工作模式 STM32的GPIO八种模式明解STM32—GPIO理论基础知识篇之八种工作模式stm32cubemx hal学习记录&#xff1a;GPIO输入输出[STM32G4系列] GPIO筆記 - CubeMX GPIO整理與應用 模拟量输入输出 ADC 【STM32】HAL库 STM32CubeMX教程九—ADC[通俗易懂] DAC STM32C…

Xcode 16 使用 pod 命令报错解决方案

原文请点击这个跳转 一、问题现象&#xff1a; 有人会遇到 Xcode 升级到 16 后&#xff0c;新建应用然后使用 pod init 命令会报错如下&#xff1a; Stack Ruby : ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-darwin23]RubyGems : 3.5.22Host : macOS 15.0 (24A335…

使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能

提示&#xff1a;CSDN 博主测评ONLYOFFICE 文章目录 引言技术栈环境准备安装 ONLYOFFICE 文档服务器获取 API 密钥安装 Flask 和 Requests 创建 Flask 应用项目结构编写 app.py创建模板 templates/index.html 运行应用功能详解文档上传生成编辑器 URL显示编辑器回调处理 安全性…

机器学习——损失函数、代价函数、KL散度

&#x1f33a;历史文章列表&#x1f33a; 机器学习——损失函数、代价函数、KL散度机器学习——特征工程、正则化、强化学习机器学习——常见算法汇总机器学习——感知机、MLP、SVM机器学习——KNN机器学习——贝叶斯机器学习——决策树机器学习——随机森林、Bagging、Boostin…

vxe-table 3.10+ 进阶高级用法(一),根据业务需求自定义实现筛选功能

vxe-table 是vue中非常强大的表格的&#xff0c;公司项目中复杂的渲染都是用 vxe-table 的&#xff0c;对于用的排序。筛选之类的都能支持&#xff0c;而且也能任意扩展&#xff0c;非常强大。 默认筛选功能 筛选的普通用法就是给对应的列指定参数&#xff1a; filters&#…

推荐一款好用的postman替代工具2024

Apifox 是国内团队自主研发的 API 文档、API 调试、API Mock、API 自动化测试一体化协作平台&#xff0c;是非常好的一款 postman 替代工具。 它通过一套系统、一份数据&#xff0c;解决多个系统之间的数据同步问题。只要定义好接口文档&#xff0c;接口调试、数据 Mock、接口…

MTSET可溶于DMSO、DMF、THF等有机溶剂,并在水中有轻微的溶解性,91774-25-3

一、基本信息 中文名称&#xff1a;[2-(三甲基铵)乙基]甲硫基磺酸溴&#xff1b;MTSET巯基反应染料 英文名称&#xff1a;MTSET&#xff1b;[2-(Trimethylammonium)ethyl]methanethiosulfonate Bromide CAS号&#xff1a;91774-25-3 分子式&#xff1a;C6H16BrNO2S2 分子量…

如何为电子课程创造创意

为电子课程创造一个想法&#xff0c;首先要深刻理解是什么让知识对学习者既相关又吸引人。第一步是专注于可以分解为可教部分的特定技能或专业领域。通常&#xff0c;人们从他们熟悉的东西开始&#xff0c;但真正的挑战在于将这些知识转化为一种可访问且引人入胜的学习体验。这…

安全生产管理的重要性:现状、痛点与改进之路

当前&#xff0c;安全生产管理已经成为企业管理中的关键环节&#xff0c;但现实中仍然存在诸多痛点。近年来&#xff0c;随着工业化和现代化的快速推进&#xff0c;企业在追求效益的同时&#xff0c;忽视安全管理的现象屡见不鲜。据统计&#xff0c;安全事故的发生频率仍然较高…

深度学习之 LSTM

1.1 LSTM的产生原因 ​ RNN在处理长期依赖&#xff08;时间序列上距离较远的节点&#xff09;时会遇到巨大的困难&#xff0c;因为计算距离较远的节点之间的联系时会涉及雅可比矩阵的多次相乘&#xff0c;会造成梯度消失或者梯度膨胀的现象。为了解决该问题&#xff0c;研究人…