【Rust标准库中的convert(AsRef,From,Into,TryFrom,TryInto)】

Rust标准库中的convert(AsRef,From,Into,TryFrom,TryInto)

  • 为什么需要convert库
  • AsRef(不可变引用:多用于内部字段获取值)
  • From/Into Trait | TryFrom/TryInto Trait
      • From Trait:
      • TryFrom Trait:
    • From代码示例
    • Into使用方法示例
  • 总结


为什么需要convert库

在程序设计时,开发者一般会选择将一系列类型数据打包在一起,并有所限制,一是为了代码的简洁美观和复用,二是为了给予字段访问限制(如我们只通过初始化函数赋予字段值,外部程序需要引用到内部字段但不该修改它)
提到限制,会有开发者想到使用pub 关键字,没错,pub关键字可以将内部字段暴露给外部函数,但是破坏了封装性,且没有限制可变性,有人说我们可以自己写一个函数,也Ok,但是需要注意可变性的限制 ,一般情况下,我们都不希望外部程序可以通过除特定的方法之外修改我们的字段值。
Rust为开发者提供了一揽子转换方法,不论是从基础转为派生,还是反向转换均有trait,使用者只需实现trait,便可使用其中的转换方法并不失去封装性。

AsRef(不可变引用:多用于内部字段获取值)

假设有这样一种需求,某论坛需要获取登陆者的电话号码,以便在后续论坛举办活动时给会员发去活动邀请,所以我们就需要挑选合适的方式在代码中储存信息以及分析合理性。

  1. 我们需要一个struct元组来描述用户的电话号码(这里涉及到新类型模式,不展开了,仅以简单示例):
//UserInfo.rs
#[derive(Debug)]
pub struct Phone(String);
//我们实现了简单的new函数,并包含简单的号码正确性验证。
impl Phone {pub fn new(phone_number: &str) -> Result<Self, &'static str> {if phone_number.len() == 11 {Ok(Self(phone_number.to_string()))} else {Err("Invalid phone number")}}
}
//并将其封装到包mod.rs
pub(crate) mod UserInfo;

2.我们在main.rs,写一个sendmsg方法用以表示发送短信通知:

mod user_info;
use std::error::Error;use user_info::UserInfo::Phone;fn sendmsg(phonenum: &str) -> Result<String, Box<dyn Error>> {// Simulate a call to the phone number// For simplicity, we just return the number as a stringOk(phonenum.to_string())
}
fn main() {let result = Phone::new("13324533333");match result {Ok(phone) => sendmsg(phone.0),Err(e) => todo!(),};
}
//哪里会有问题?

没错,在sendmsg(phone.0) 时会有如下报错,field 0 of Phone is private
不论是将Phone中的String设置为pub,还是使用可变引用都破坏了我们代码的封装性。

正确地方法:实现trait AsRef:

//在UserInfo.rs中添加如下实现
impl AsRef<str> for Phone {fn as_ref(&self) -> &str {&self.0}
}//main.rs中使用入下调用
let result: Result<Phone, &str> = Phone::new("13324533333");let _ = match result {Ok(phone) => sendmsg(phone.as_ref()),Err(_e) => todo!(),};

如此,我们既不破坏封装性,又可以使用Rust convert的系列方法。

From/Into Trait | TryFrom/TryInto Trait

用以值到值的转换,简单来说,From提供细分内部类型向外部总类型转换,Into可以理解为为了适配孤儿规则而存在的,当前的版本1.82.0一般情况下不会有人主动实现Into,由于Rust的一揽子trait ,实现了From就等于实现了Into,非常方便。
不论是实际应用上,还是Rust中的举例来讲,From确实非常适合工程下的错误处理。
From有如下特点:

  1. 涉及到的转换不可以失败。
  2. 转换必须无损,如不丢失数据
  3. 转换必须保值,即不丢失精度
  4. 必须式是显而易见的转换,如 AuthError—> ServerError
//仅作代码示例
#[derive(Debug)]
enum ServerError {//总类型DatabaseError(String),//细分类型NetworkError(std::io::Error),TimeoutError(VarError),AuthError(Error),
}

ps: 如果不符合上述,则需要使用TryFrom,同样的,实现了TryFrom等于实现了TryInto。

From Trait:

pub trait From<T>: Sized {// Required methodfn from(value: T) -> Self;
}
//其直接返回类型。

TryFrom Trait:

pub trait TryFrom<T>: Sized {type Error;// Required methodfn try_from(value: T) -> Result<Self, Self::Error>;
}
//其返回Result,允许失败。

From代码示例

use std::{env::VarError,fmt::{Display, Error},
};
//仅作代码示例
#[derive(Debug)]
enum ServerError {DatabaseError(String),NetworkError(std::io::Error),TimeoutError(VarError),AuthError(Error),
}
impl Display for ServerError {fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {match self {ServerError::DatabaseError(err) => write!(f, "Database error: {}", err),ServerError::NetworkError(err) => write!(f, "Network error: {}", err),ServerError::TimeoutError(err) => write!(f, "Timeout error: {}", err),ServerError::AuthError(err) => write!(f, "AuthError error: {}", err),}}
}
impl From<String> for ServerError {fn from(err: String) -> Self {ServerError::DatabaseError(err)}
}impl From<std::io::Error> for ServerError {fn from(err: std::io::Error) -> Self {ServerError::NetworkError(err)}
}
impl From<Error> for ServerError {fn from(err: Error) -> Self {ServerError::AuthError(err)}
}impl From<VarError> for ServerError {fn from(err: VarError) -> Self {ServerError::TimeoutError(err)}
}fn handle_server_error() -> Result<(), String> {Err(String::from("handle_server_error"))
}
fn handle_server_error1() -> Result<(), std::io::Error> {Ok(())
}
fn handle_server_error2() -> Result<(), VarError> {Ok(())
}
fn handle_server_error3() -> Result<(), Error> {Ok(())
}fn func() -> Result<(), ServerError> {handle_server_error()?;handle_server_error1()?;handle_server_error2()?;handle_server_error3()?;Ok(())
}fn main() {match func() {Ok(_) => println!("Success"),Err(e) => eprintln!("Error: {:?}", e),}
}

如此,开发者既可以细分错误类型,并定制化输出内容,又可以统一result类型,并使用【?】将error向上抛出
同时,Rust也提供了thiserror,anyhow等错误处理包,通过扩展宏标记后,会生成大部分的样板代码,同时通过trace等方式,将上下文串联起来更加方便的排查问题。

Into使用方法示例

此示例代码来源于Rust By Example

use std::convert::Into;#[derive(Debug)]
struct Number {value: i32,
}impl Into<Number> for i32 {fn into(self) -> Number {Number { value: self }}
}fn main() {let int = 5;// Try removing the type annotationlet num: Number = int.into();println!("My number is {:?}", num);
}

总结

Rust中的转换,不仅仅使用方便,更重要的是可以告知阅读者我们在做什么。

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

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

相关文章

自扶正救生艇,保障水上救援的安全卫士_鼎跃安全

在应急事件中&#xff0c;自扶正救生艇能够发挥关键的救援和保障作用&#xff0c;确保救援人员和被困人员的生命安全&#xff0c;尤其在极端天气或突发水上事故中展现出明显优势。 在救援过程中如果遭遇翻船&#xff0c;救生艇能够迅速恢复正常姿态&#xff0c;确保救援人员不会…

提升网站安全性 HTTPS的重要性与应用指南

内容概要 在如今数字化快速发展的时代&#xff0c;网站安全显得尤为重要。许多用户在访问网站时&#xff0c;尤其是涉及个人信息或金融交易时&#xff0c;对数据传输的安全性有着高度的关注。HTTPS&#xff08;超文本传输安全协议&#xff09;正是为了满足这种需求而诞生的。通…

QT——自定义控件绘图

一.QPaintEvent绘图事件 QPaintEvent是QT中一个重要的类&#xff0c;专门用于绘图事件。当QT视图组件需要重绘制自己的一部分时&#xff0c;就会产生该事件&#xff0c;通常发生在以下几种情况。 窗口第一次显示时&#xff1a;当窗口或控件第一次出现在屏幕中&#xff0c;系统…

【Python · Pytorch】人工神经网络 ANN(上)

【Python Pytorch】人工神经网络 ANN&#xff08;上&#xff09; 0. 生物神经网络1. 人工神经网络定义2. 人工神经网络结构2.1 感知机2.2 多层感知机2.3 全连接神经网络2.4 深度神经网络 2. 训练流程※ 数据预处理 (Data Preprocessing) 3. 常见激活函数3.1 Sigmoid / Logisti…

【Redis_Day2】在Linux中安装Redis5

本篇涉及Linux中的三条指令&#xff1a;su&#xff1b;apt&#xff1b;vim&#xff0c;可以了解后再来浏览本篇。或在评论留言。 【Redis_Day2】在Linux中安装Redis5 安装修改配置文件使用redis-cli连接服务器 安装 Linux版本选择Ubuntu22.04 Redis版本选择Redis5 登录Ubunt…

第1篇 引言

一、AIGC概念 1、AIGC定义 AIGC&#xff0c;即生成式人工智能&#xff08;Artificial Intelligence Generated Content&#xff09;&#xff0c;是指利用人工智能技术自动生成或辅助创作内容的过程和结果。 简单来说&#xff1a;过去&#xff0c;写文章、画张图、唱首歌、弄个…

深度学习---------------------------------Transformer

目录 Transformer架构多头注意力有掩码的多头注意力基于位置的前馈网络层归一化信息传递预测总结代码多头注意力使用多个头并行计算选择缩放点积注意力作为每一个注意力头测试该部分总代码Transformer基于位置的前馈网络改变张量的最里层维度的尺寸对比不同维度的层归一化和批量…

世界时区划分

1. AoE &#xff08;Anywhere on Earth&#xff09;代表地球上最后一个时区的时间&#xff0c;是全球范围内最晚的时间&#xff0c;通常用于截止日期。 2. UTC/GMT &#xff08;协调世界时/格林威治时间&#xff09;是全球的标准时间&#xff0c;所有时区都是基于UTC计算的。…

qt QImage详解

1、概述 QImage是Qt框架中用于处理图像数据的一个核心类。与QPixmap不同&#xff0c;QImage是在内存中直接存储图像像素数据的&#xff0c;这使得它适用于需要直接访问和修改像素的应用场景&#xff0c;比如图像处理算法、图像绘制以及图像分析等。QImage支持多种图像格式&…

DAY75WEB 攻防-验证码安全篇接口滥用识别插件复用绕过宏命令填入滑块类

知识点&#xff1a; 1、验证码简单机制-验证码过于简单可爆破 2、验证码重复使用-验证码验证机制可绕过 3、验证码智能识别-验证码图形码被可识别 4、验证码接口调用-验证码触发接口可枚举 图片验证码-识别插件-登录爆破&接口枚举 验证码识别绕过等技术适用于&#x…

字符串左旋 (干货无废话)

题目内容&#xff1a;实现一个函数&#xff0c;可以左旋字符串中的k个字符 例如&#xff1a;ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 画图解释&#xff1a; 上图分别是向左挪1次&#xff0c;2次&#xff0c;3次&#xff0c;4次&#xff0c;5次后的结果…

QML基础语法2

函数 函数格式&#xff1a; function关键字 函数名(参数名1:参数类型,参数名2:参数类型,...):返回值类型{} 其中&#xff1a; 函数名必须以小写字符开头&#xff0c;后面驼峰可以有多个参数或者没有参数参数类型可以不写返回值类型也可以不写 如何调用&#xff1a;通过id点…

Mac 配置SourceTree集成云效

1、背景 工作使用的是自己的笔记本&#xff0c;一个是比较卡&#xff0c;在一个是敏感信息比较多还是使用公司的电脑&#xff0c;但是系统是Mac就很麻烦&#xff0c;在网上找了帖子记录一下 2、配置 打开终端 ssh-keygen -t rsa #一直回车就行 cd .ssh cat id_rsa.pub #查…

Kubernetes中常见的volumes数据卷

华子目录 volumesk8s支持的卷的类型emptyDir卷功能emptyDir的使用场景示例 hostPath卷功能用法安全隐患示例 nfs卷功能应用示例&#xff1a;部署一台nfs服务器并在所有k8s节点中安装nfs-utils volumes 容器中文件在磁盘上是临时存放的&#xff0c;这给容器中运行的特殊应用程序…

PaddleNLP的FAQ问答机器人

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【DDRNet模型创新实现人像分割】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…

Windows的MySQL开机自动启动问题

标题 问题描述 问题描述 在Windows系统中&#xff0c;我设置好了MySQL服务为自动启动&#xff0c;但在开机后发现MySQL服务任没有自动运行。我有点苦恼&#xff0c;每次连接MySQL&#xff0c;都要进入计算机管理&#xff0c;手动打开。 解决方法&#xff1a; 1.前提安装好MySQ…

基于Spring Boot的私房菜定制上门服务系统的设计与实现

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统私房菜定制上门服务系统信息管理难度大&#xff0c;容错率…

计算机毕业设计 | 基于SpringBoot的健身房管理系统(附源码)

1&#xff0c;项目背景 随着人们生活水平的提高和健康意识的增强&#xff0c;健身行业逐渐兴起并迅速发展。而现代化的健身房管理系统已经成为健身房发展的必备工具之一。传统的健身房管理方式已经无法满足现代化健身房的需求&#xff0c;需要一种更加高效、智能、安全的管理系…

LeetCode 0685.冗余连接 II:并查集(和I有何不同分析)——详细题解(附图)

【LetMeFly】685.冗余连接 II&#xff1a;并查集&#xff08;和I有何不同分析&#xff09;——详细题解(附图) 力扣题目链接&#xff1a;https://leetcode.cn/problems/redundant-connection-ii/ 在本问题中&#xff0c;有根树指满足以下条件的 有向 图。该树只有一个根节点&…

前端请求后端接口报错(blocked:mixed-content),以及解决办法

报错原因&#xff1a;被浏览器拦截了&#xff0c;因为接口地址不是https的。 什么是混合内容&#xff08;Mixed Content&#xff09; 混合内容是指在同一页面中同时包含安全&#xff08;HTTPS&#xff09;和非安全&#xff08;HTTP&#xff09;资源的情况。当浏览器试图加载非…