当前位置: 首页 > news >正文

rust的类型转换和一些智能指针用法(四)

基础类型

使用 as 关键字:用于基本数值类型之间的转换,例如将 i32 转换为 u32。
例子:let x: i32 = 10; let y: u64 = x as u64;
使用标准库中的转换方法:如 from()into() 方法,这些方法通常用于无风险的转换,或者当转换可能失败时返回 Result 类型。
例子:let x: i32 = 10; let y: u64 = u64::from(x);(如果转换是安全的)
使用 try_into()try_from():当转换有可能失败时(例如,当试图将较大的整数类型转换为较小的整数类型时),这些方法会返回一个 Result 类型,允许错误处理。
例子:let x: i32 = 10; let y: u8 = x.try_into().unwrap();
布尔类型转换
布尔类型不能直接转换为数值类型,也不能从数值类型直接转换。
如果需要基于布尔值生成数值,可以使用条件表达式:let num = if bool_val { 1 } else { 0 };
字符与数值类型转换
字符类型 (char) 与整数类型之间的转换也需要显式操作。
例子:将 char 转换为其对应的 Unicode 编码(一个整数):let num = 'a' as u32;
从整数转换到 char 时需要保证整数是一个有效的 Unicode 码点:let ch = std::char::from_u32(97).unwrap();
元组和数组
元组和数组的转换通常涉及到元素的解构或重新组合,而不是类型转换。
例如,从元组转换到不同类型的元组或提取元组中的值:let tup = (1, 2.0, 'a'); let (x, y, z) = tup;

其他类型转字符串

1.使用 to_string() 方法
这是转换任何实现了 Display trait 的类型到字符串的最简单和最直接的方法。i32 和 f64 都实现了 Display trait,所以可以直接使用 to_string() 方法。

let num_i32 = 32;
let num_f64 = 10.5;let str_from_i32 = num_i32.to_string();
let str_from_f64 = num_f64.to_string();println!("i32 to String: {}", str_from_i32);  // 输出:i32 to String: 32
println!("f64 to String: {}", str_from_f64);  // 输出:f64 to String: 10.5

2.使用 format! 宏

let num_i32 = 32;
let num_f64 = 10.5;// 使用 format! 宏进行基本转换
let str_from_i32 = format!("{}", num_i32);
let str_from_f64 = format!("{}", num_f64);// 使用 format! 宏指定浮点数的精度
let formatted_f64 = format!("{:.2}", num_f64);println!("i32 to String: {}", str_from_i32);  // 输出:i32 to String: 32
println!("f64 to String: {}", str_from_f64);  // 输出:f64 to String: 10.5
println!("Formatted f64: {}", formatted_f64);  // 输出:Formatted f64: 10.50

字符串转整形,或者浮点型

let s = "42".to_string();
let result: Result<i32, _> = s.parse();
match result {Ok(num) => println!("Converted string to i32: {}", num),Err(e) => println!("Failed to convert string to i32: {}", e),
}let s = "3.14".to_string();
let result: Result<f64, _> = s.parse();
match result {Ok(num) => println!("Converted string to f64: {}", num),Err(e) => println!("Failed to convert string to f64: {}", e),
}

Result 和 Option 核心枚举类型常用的方法

Option
Option<T>
Option<T> 类型用于可能存在或可能不存在的值。它有两个变体:Some(T) 表示有一个值,和 None 表示没有值。常用方法:unwrap():提取 Some 的值或在 None 时引发 panic。
let some_option = Some("Hello");
println!("{}", some_option.unwrap());  // 输出 "Hello"unwrap_or():提取 Some 的值或在 None 时返回一个默认值。
let none_option: Option<&str> = None;
println!("{}", none_option.unwrap_or("Default"));  // 输出 "Default"map():如果是 Some(T),应用一个函数到内部值并返回一个新的 Optionlet num_option = Some(5);
let squared = num_option.map(|x| x * x);
println!("{:?}", squared);  // 输出 Some(25)and_then():如果是 Some(T),则应用一个返回 Option<U> 的函数,否则返回 None
let some_string = Some("5");
let parsed = some_string.and_then(|s| s.parse::<i32>().ok());
println!("{:?}", parsed);  // 输出 Some(5)
Result
unwrap():提取 Ok 的值或在 Err 时引发 panic。
let ok_result: Result<i32, &str> = Ok(10);
println!("{}", ok_result.unwrap());  // 输出 10unwrap_or():提取 Ok 的值或在 Err 时返回一个默认值。
let err_result: Result<i32, &str> = Err("error");
println!("{}", err_result.unwrap_or(0));  // 输出 0map():如果是 Ok(T),应用一个函数到内部值并返回一个新的 Resultlet ok_result = Ok(2);
let doubled = ok_result.map(|x| x * 2);
println!("{:?}", doubled);  // 输出 Ok(4)and_then():如果是 Ok(T),则应用一个返回 Result<U, E> 的函数,否则返回 Err(E)
let ok_result = Ok("10");
let parsed = ok_result.and_then(|s| s.parse::<i32>().map_err(|e| "parse error"));
println!("{:?}", parsed);  // 输出 Ok(10)or_else():如果是 Err(E),应用一个函数来创建一个新的 Result,否则保持 Ok(T)
let err_result: Result<i32, &str> = Err("error");
let fixed = err_result.or_else(|_| Ok(0));
println!("{:?}", fixed);  // 输出 Ok(0)
if let
let some_option = Some(10);if let Some(value) = some_option {println!("Got a value: {}", value);
} else {println!("Got nothing!");
}let result: Result<i32, String> = Ok(20);if let Ok(num) = result {println!("Success with number: {}", num);
} else {println!("Failed!");
}let some_string = Some("Hello, World!");if let Some(length) = some_string.map(|s| s.len()) {println!("The string length is: {}", length);
} else {println!("No string!");
}let result: Result<i32, String> = Err("Something went wrong".to_string());if let Err(e) = result {println!("Error occurred: {}", e);
}
// 也可以添加一个 else 分支处理成功情况
else {println!("Success, no errors!");
}let result: Result<i32, String> = Err("failed".to_string());// 使用 map_err 转换错误类型,然后使用 if let 检查
if let Err(e) = result.map_err(|e| format!("Error: {}", e)) {println!("{}", e);
}

常用智能指针

Box 在 Rust 中是一个非常有用的类型,它允许你将数据放在堆上而不是栈上

常用的几个场景

1. 处理大数据
当你有一个非常大的数据结构时,将其放在栈上可能会导致栈溢出或不必要的性能负担。使用 Box 可以避免这些问题,因为它将数据存储在堆上。示例:
let large_array = Box::new([0u8; 1000000]);  // 1MB的空间
这里,一个大型的数组被分配在堆上,而不是占用宝贵的栈空间。2. 递归类型
在定义递归数据结构时,比如链表或树,你通常需要使用 Box 来间接持有类型的一部分。这是因为 Rust 需要在编译时知道类型的确切大小,而递归类型无法在不进行某种形式的间接寻址的情况下给出确切大小。示例:
enum List<T> {Cons(T, Box<List<T>>),Nil,
}use List::{Cons, Nil};let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
这里的链表 List 使用 Box 来持有其递归部分,这使得 Rust 能够处理变量大小的类型。3. 确保类型拥有 trait 对象
当你需要创建一个动态分发的类型时,通常需要使用 trait 对象。Trait 对象(如 Box<dyn SomeTrait>)允许你在运行时存储和调用实现了该 trait 的任何类型的实例。示例:trait Speak {fn speak(&self);
}struct Dog;
struct Cat;impl Speak for Dog {fn speak(&self) {println!("Woof!");}
}impl Speak for Cat {fn speak(&self) {println!("Meow!");}
}let animals: Vec<Box<dyn Speak>> = vec![Box::new(Dog),Box::new(Cat),
];for animal in animals {animal.speak();
}
在这个示例中,不同类型的动物都实现了 Speak trait,并且通过 Box<dyn Speak> 存储在同一个向量中,使得可以在运行时动态地调用它们的 speak 方法。4. 接口的强制所有权
有时,你可能想要确保某个函数完全拥有它接收的数据,Box<T> 可以用来明确这种所有权转移。示例:
fn process_data(data: Box<Data>) {// 处理数据
}let data = Box::new(Data::new());
process_data(data);
RefCell 与 Rc 的使用

这种组合允许在单线程环境中实现多个可变引用的共享数据。Rc 本身不允许可变引用,因为它只保证数据的多所有者共享,而不提供数据修改的能力。结合 RefCell,它提供了一种运行时检查的方式来借用可变或不可变的引用。

示例:使用 RefCell 与 Rc
假设我们有一个结构体 Person,它存储在多个地方,并且我们希望在运行时根据需要修改其字段:

use std::rc::Rc;
use std::cell::RefCell;struct Person {name: String,age: u32,
}fn main() {let person = Rc::new(RefCell::new(Person {name: "Alice".to_string(),age: 30,}));{let mut p = person.borrow_mut();p.age += 1;}{let p = person.borrow();println!("{} is {} years old.", p.name, p.age);}
}

例子2 ,共享多个写入和读取

use std::rc::Rc;
use std::cell::RefCell;struct TextBox {content: Rc<RefCell<String>>,
}impl TextBox {fn new(content: &Rc<RefCell<String>>) -> TextBox {TextBox {content: Rc::clone(content),}}fn display(&self) {println!("{}", self.content.borrow());}fn append(&self, text: &str) {println!("Before append: {}", self.content.borrow());self.content.borrow_mut().push_str(text);println!("After append: {}", self.content.borrow());}
}fn main() {let shared_text = Rc::new(RefCell::new(String::from("Hello")));let text_box1 = TextBox::new(&shared_text);text_box1.append(" world");text_box1.append(" gitxuzan");let text_box2 = TextBox::new(&shared_text);text_box2.display(); // 应该输出 "Hello world gitxuzan"
}

相关文章:

rust的类型转换和一些智能指针用法(四)

基础类型 使用 as 关键字&#xff1a;用于基本数值类型之间的转换&#xff0c;例如将 i32 转换为 u32。 例子&#xff1a;let x: i32 10; let y: u64 x as u64; 使用标准库中的转换方法&#xff1a;如 from() 和 into() 方法&#xff0c;这些方法通常用于无风险的转换&#…...

探索大模型技术及其前沿应用——TextIn文档解析技术

前言 中国图象图形大会&#xff08;CCIG 2024&#xff09;于近期在西安召开&#xff0c;此次大会将面向开放创新、交叉融合的发展趋势&#xff0c;为图像图形相关领域的专家学者和产业界同仁&#xff0c;搭建一个展示创新成果、展望未来发展&#xff0c;集高度、深度、广度三位…...

Java HashMap 扩容机制深度解析

HashMap 的一个关键性能优化就是扩容机制&#xff0c;即在哈希表达到一定负载因子时&#xff0c;自动进行扩容&#xff0c;以保持检索效率。 在这篇文章中&#xff0c;我们将深入研究 HashMap 的扩容机制&#xff0c;了解其原理和影响因素。 1. 初始容量和负载因子 在深入了解…...

一、Electron 环境初步搭建

新建一个文件夹&#xff0c;然后进行 npm init -y 进行初始化&#xff0c;然后我们在进行 npm i electron --save-dev , 此时我们按照官网的教程进行一个初步的搭建&#xff0c; 1.在 package.json 文件进行修改 {"name": "electron-ui","version…...

ffmpeg编码器编码元数据的过程以及编码前后的差异

编码方式为avcodec_send_frame&#xff1a;将原始帧发送到编码器进行编码 编码过程完成于avcodec_receive_packet&#xff1a;从编码器接收编码后的压缩数据&#xff0c;也就是说已经编码压缩完成了&#xff0c;并存储到avpacket中&#xff0c;此时元数据被分割成多个NALU单元&…...

AB测试学习(附有相关代码)

目录 一、基本概念1. 定义2. 作用3. 原理 二、实验基本原则三、实验步骤四、实验步骤详解1. 确定实验目的2. 确定实验变量3. 实验指标设计3.1 实验指标类型&#xff08;按作用区分&#xff09;3.1.1 核心指标3.1.2 驱动指标&#xff08;跟踪指标&#xff09;3.1.3 护栏指标 3.2…...

用idea将java文件打成jar包

一、用idea将java文件打成jar包 1、在idea上选择file—Project Structure 2、Artifacts —点–JAR—From modules with dependencies 3、选择要打包的java文件 4、Build — Build Artifacts 5、找到刚才添加的Artifacts直接Build 6、生成jar包文件...

Ansible——group模块

目录 参数总结 语法示例 创建用户组 删除用户组 设置组的 GID 创建系统组 修改组的 GID 添加用户组并附加其他组属性 删除指定 GID 的用户组 帮助信息 Playbook示例 基本示例 1. 创建用户组 2. 删除用户组 进阶示例 1. 修改组的 GID 2. 综合管理多个用户组 3…...

Sql注入-报错注入

报错注入&#xff08;Error-Based Injection&#xff09;是一种通过引起数据库报错并从错误信息中提取有用信息的SQL注入攻击手法&#xff1b;攻击者利用数据库在处理异常情况时返回的错误消息&#xff0c;来推断出数据库结构、字段名甚至数据内容&#xff1b;这种攻击方法依赖…...

pyqt 回车触发两次editingFinished的解决办法

在英文Qt论坛看到的解决办法 def editingFinished_triger(self):#self.sender() is the QlineEditif not self.sender().isModified(): returnself.sender().setModified(False)#treat code ...#treat code ...下面是一个错误使用editingFinished的例子 在上面界面中有一个文本…...

爬取股票数据python

最近在搜集数据要做分析&#xff0c;一般的数据来源是一手数据&#xff08;生产的&#xff09;和二手数据&#xff08;来自其他地方的&#xff09;。 今天我们爬取同花顺这个网站的数据。url为&#xff1a;https://data.10jqka.com.cn/ipo/xgsgyzq/ 话不多说直接上代码。有帮…...

每日新闻掌握【2024年6月4日 星期二】

2024年6月4日 星期二 农历四月廿八 TOP大新闻 张雪峰近2万元志愿填报服务已售罄 2024年高考临近&#xff0c;考生紧张的是考场上能否如常发挥&#xff0c;而考场之下&#xff0c;家长们已经开始为孩子的志愿填报焦心。峰学蔚来是由张雪峰打造专门提供高考志愿填报服务的APP&am…...

智谱AI 发布最新开源模型GLM-4-9B,通用能力超Llama-3-8B,多模态版本比肩GPT-4V

自 2023 年 3 月 14 日开源 ChatGLM-6B 以来&#xff0c;GLM 系列模型受到广泛关注和认可。特别是 ChatGLM3-6B 开源以后&#xff0c;开发者对智谱AI 第四代模型的开源充满期待。 为了使小模型&#xff08;10B 以下&#xff09;具备更加强大的能力&#xff0c;GLM 技术团队进行…...

从写简历到谈薪资的最全教程

从写简历到谈薪资的最全教程 目录简历注意事项举个例子写简历投递简历也有技巧模拟面试的重要性面试经验怎么刷不断迭代达越来越强斗智斗勇谈薪资拿到offer就结束了吗&#xff1f;我能给你的帮助 目录 大家好&#xff0c;我是一名普通本科毕业的学生&#xff0c;工作数年&#…...

Vue3 响应式API:高级函数(二)

shallowRef() shallowRef 是一个特殊的 ref 创建函数&#xff0c;它允许你创建一个只追踪顶层属性变化的响应式引用。与 ref 不同的是&#xff0c;shallowRef 创建的响应式引用对其内部值的深层嵌套属性是不敏感的&#xff0c;也就是说&#xff0c;只有当 shallowRef 的 .valu…...

『大模型笔记』什么是提示词注入(Prompt Injection)攻击?

什么是提示词注入(Prompt Injection)攻击? 文章目录 一. 什么是提示词注入(Prompt Injection)?二. 参考文献一. 什么是提示词注入(Prompt Injection)? 想花1美元买一辆新SUV吗?有人真的尝试过这样做。事实上,他们在一家特定汽车经销商的网站聊天机器人上进行了尝试。为了…...

SD-WAN与IPSec的对比

在现代企业中&#xff0c;随着网络环境的日益复杂&#xff0c;SD-WAN和IPSec作为两种关键的网络技术&#xff0c;各有其独特的优势和应用场景。那么&#xff0c;SD-WAN和IPSec究竟有什么不同&#xff1f;企业在不同情况下应该选择哪种技术呢&#xff1f; SD-WAN和IPSec的基本概…...

Ceph入门到精通-ceph经典盘符飘逸问题处理步骤

在Ceph存储系统中,"盘符飘逸"通常指的是Ceph OSD(Object Storage Daemon)使用的磁盘在系统重启后没有被正确挂载或识别。这可能是由于多种原因造成的,例如磁盘连接问题、驱动问题或配置错误。以下是解决此问题的步骤: 确认磁盘状态: 使用lsblk或fdisk -l命令来…...

【CV算法工程师必看】作为一个图像算法工程师,需要会什么,要学哪些技术栈?

作为一个图像算法工程师,除了基本的编程技能和理论知识,还需要掌握一系列的技术栈。以下是详细的技能和技术栈分类: 编程语言 Python: 主要用于快速开发和原型设计。常用库:OpenCV、Pillow、NumPy、SciPy、Scikit-image、TensorFlow、PyTorch。C++: 高性能要求的项目中广…...

【造化弄人:计算机系大学生真的象当年的高速公路收费员一样吗?】

曾经高速公路的收费员是多么的自豪和骄傲&#xff0c;按照常逻辑&#xff0c;车是越来越多&#xff0c;收费员应该越来越多&#xff1f;但现实情况&#xff0c;大家有目共睹&#xff01; 不论你的车子怎么跑&#xff0c;只要上高速就要交费&#xff0c;那时候的收费员&#xf…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

CSS3相关知识点

CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...