rust学习-panic

panic!

panic示例

use std::fs::File;
fn main() {// 使用 Result 类型来处理潜在的错误部分中的Result 枚举// enum Result<T, E> {//    Ok(T),//    Err(E),// }// // File::open 函数的返回值类型是 Result<T, E>// T 放入了成功值的类型 std::fs::File,它是一个文件句柄// E 被用在失败值上时 E 的类型是 std::io::Errorlet f = File::open("hello.txt");// 如果按照如下方式使用,则报错// let f: u32 = File::open("hello.txt");let f = match f {Ok(file) => file,Err(error) => {panic!("Problem opening the file: {:?}", error)},};
}

嵌套match

use std::fs::File;
use std::io::ErrorKind;fn main() {let f = File::open("hello.txt");let f = match f {Ok(file) => file,// 连错误原因都要分类讨论Err(error) => match error.kind() {ErrorKind::NotFound => match File::create("hello.txt") {Ok(fc) => fc,// io::Error 是一个标准库的结构体。它有一个返回 io::ErrorKind 值的 kind 方法Err(e) => panic!("Problem creating the file: {:?}", e),},other_error => panic!("Problem opening the file: {:?}", other_error),},};
}

消除match

use std::fs::File;
use std::io::ErrorKind;// 为了消除大量match的写法
fn main() {let f = File::open("hello.txt").unwrap_or_else(|error| {if error.kind() == ErrorKind::NotFound {File::create("hello.txt").unwrap_or_else(|error| {panic!("Problem creating the file: {:?}", error);})} else {panic!("Problem opening the file: {:?}", error);}});
}
// Result<T, E> 类型定义了很多辅助方法来处理各种情况
// unwrap,似于match 语句
// 如果 Result 值是成员 Ok,unwrap 会返回 Ok 中的值
// 如果 Result 是成员 Err,unwrap 会调用 panic!use std::fs::File;fn main() {let f = File::open("hello.txt").unwrap();
}
expect:选择 panic! 的错误信息
use std::fs::File;fn main() {let f = File::open("hello.txt").expect("Failed to open hello.txt");
}

错误透传

use std::io;
use std::io::Read;
use std::fs::File;// 返回一个包含用户名的 Ok 值,或一个包含 io::Error 的 Err 值
fn read_username_from_file() -> Result<String, io::Error> {let f = File::open("hello.txt");// 用match的原因:当 Err 时不再调用 panic!// 提早返回并将 File::open 返回的错误值作为函数的错误返回值传递给调用者let mut f = match f {Ok(file) => file,Err(e) => return Err(e),};let mut s = String::new();match f.read_to_string(&mut s) {Ok(_) => Ok(s),// 不需要显式调用 return,因为这是函数最后一个表达式Err(e) => Err(e),}
}fn main() {let result = read_username_from_file();match result {Ok(info) => {println!("info={:?}", info);},Err(e) => {println!("err={:?}", e);}}
}// 文件不存在时,打印结果如需啊
// err=Os { code: 2, kind: NotFound, message: "No such file or directory" }

错误透传简写

use std::io;
use std::io::Read;
use std::fs::File;fn read_username_from_file() -> Result<String, io::Error> {// Result 值之后的 ? 被定义为与处理 Result 值的 match 表达式有完全相同的工作方式// 如果 Result 的值是 Ok,这个表达式将会返回 Ok 中的值,程序将继续执行// 如果值是 Err,Err 中的值将作为整个函数的返回值// 错误值就被传播给了调用者//// 与match的不同// ? 运算符所使用的错误值被传递给了 from 函数,它定义于标准库的 From trait 中// 其用来将错误从一种类型转换为另一种类型// 当 ? 运算符调用 from 函数时,收到的错误类型被转换为由当前函数返回类型所指定的错误类型// 只要每一个错误类型都实现 from 函数来定义如何将自身转换为返回的错误类型,? 运算符会自动处理这些转换let mut f = File::open("hello.txt")?;let mut s = String::new();f.read_to_string(&mut s)?;Ok(s)
}fn main() {let result = read_username_from_file();match result {Ok(info) => {println!("info={:?}", info);},Err(e) => {println!("err={:?}", e);}}
}
use std::io;
use std::io::Read;
use std::fs::File;fn read_username_from_file() -> Result<String, io::Error> {let mut s = String::new();File::open("hello.txt")?.read_to_string(&mut s)?;Ok(s)
}fn main() {let result = read_username_from_file();match result {Ok(info) => {println!("info={:?}", info);},Err(e) => {println!("err={:?}", e);}}
}
use std::io;
use std::fs;// Rust 提供了名为 fs::read_to_string 的函数
// 它会打开文件、新建一个 String、读取文件的内容,并将内容放入 String,接着返回它
fn read_username_from_file() -> Result<String, io::Error> {fs::read_to_string("hello.txt")
}fn main() {let result = read_username_from_file();match result {Ok(info) => {println!("info={:?}", info);},Err(e) => {println!("err={:?}", e);}}
}

? 运算符可被用于返回值类型为 Result 的函数

use std::fs::File;
fn main() {let f = File::open("hello.txt")?;
}// 编译报错,遇到如下问题
// the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
// the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`

当期望在不返回 Result 的函数中调用其他返回 Result 的函数时使用 ?
有两种方法修复这个问题:
(1)将函数返回值类型修改为 Result<T, E>
(2)通过合适的方法使用 match 或 Result 的方法之一来处理 Result<T, E>

use std::error::Error;
use std::fs::File;// Box<dyn Error> 被称为 “trait 对象”(trait object)
// Box<dyn Error> 为使用 ? 时 main 允许返回的 “任何类型的错误”
fn main() -> Result<(), Box<dyn Error>> {let f = File::open("hello.txt")?;Ok(())
}// main 函数是特殊的,其必须返回什么类型是有限制的
// main 函数的一个有效的返回值是 (),同时出于方便,另一个有效的返回值是 Result<T, E>

不使用–release

当不使用 --release 参数运行 cargo build 或 cargo run 时,debug 标识会默认启用

fn main() {let v = vec![1, 2, 3];v[99];
}
// 使用RUST_BACKTRACE=1运行cargo run
RUST_BACKTRACE=1 cargo run cargo runFinished dev [unoptimized + debuginfo] target(s) in 0.02sRunning `/Users/hello/hello_cargo/target/debug/hello_cargo cargo run`
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5
stack backtrace:0: rust_begin_unwindat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:578:51: core::panicking::panic_fmtat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:67:142: core::panicking::panic_bounds_checkat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:162:53: <usize as core::slice::index::SliceIndex<[T]>>::indexat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/slice/index.rs:261:104: core::slice::index::<impl core::ops::index::Index<I> for [T]>::indexat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/slice/index.rs:19:95: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::indexat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/alloc/src/vec/mod.rs:2691:96: hello_cargo::mainat ./main.rs:4:57: core::ops::function::FnOnce::call_onceat /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

使用–release

如果需要项目的最终二进制文件越小越好,panic 时通过在 Cargo.toml 的 [profile] 部分增加 panic = ‘abort’,可以由展开切换为终止。如果想要在release模式中 panic 时直接终止:

[profile.release]
panic = 'abort'

当执行这个宏时,程序会打印出一个错误信息,展开并清理栈数据

fn main() {panic!("crash and burn");
}
release % ls -l
-rwxr-xr-x  1  staff  477536  7 14 12:15 hello_cargodebug % ls -l
-rwxr-xr-x    1  staff  483016  7 14 12:13 hello_cargohello_cargo % ./target/debug/hello_cargo
thread 'main' panicked at 'crash and burn', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtracehello_cargo % ./target/release/hello_cargo
thread 'main' panicked at 'crash and burn', src/main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
zsh: abort      ./target/release/hello_cargo

其他示例

pub struct Guess {value: i32,
}impl Guess {pub fn new(value: i32) -> Guess {if value < 1 || value > 100 {panic!("Guess value must be between 1 and 100, got {}.", value);}Guess {value}}pub fn value(&self) -> i32 {self.value}
}

总结

(1)当项目最终准备好发布时,可以使用 cargo build --release 来优化编译项目。这会在 target/release 而不是 target/debug 下生成可执行文件。这些优化可以让 Rust 代码运行的更快,不过启用这些优化也需要消耗更长的编译时间
(2)使用 Result 来告诉代码调用者他需要处理潜在的成功或失败

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

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

相关文章

【css】用css样式快速写右上角badge徽标,颜色设置为渐变色

先看效果展示&#xff0c;已公开显示在图片卡片的右上角。 首先是dom代码&#xff1a;需要两个view或者div&#xff0c;public-badge是“已公开”那个矩形&#xff0c;show-signal是右边那个下三角&#xff0c;也就是阴影部分&#xff0c;这样看起来比较有立体感。 <view…

Java基础-内部类

内部类指的是在一个类的内部定义的类&#xff0c;Java 中存在四种内部类&#xff0c;分别是成员内部类、局部内部类、静态内部类和匿名内部类。 成员内部类 成员内部类在类文件中与成员变量和成员方法并列&#xff0c;作为类的成员存在。 成员内部类可以访问外部类的所有成员…

虚拟化技术及实时虚拟化概述

版权声明&#xff1a;本文为本文为博主原创文章&#xff0c;未经本人同意&#xff0c;禁止转载。如有问题&#xff0c;欢迎指正。博客地址&#xff1a;https://www.cnblogs.com/wsg1100/ 文章目录 一、前言二、分时系统三、虚拟化介绍四、虚拟化实现方式及分类模拟器Type2虚拟化…

欧姆龙PLC联网

一、设备信息确认 左上角的为PLC型号,如图该PLC型号为CP1H,不同型号的欧姆龙PLC通讯方面有什么差别呢? 通讯能力和方式不同: 有些型号PLC自带网口,有些则需要扩展(上图中右侧的两个红框内为后扩展的通讯口,扩展模块可以随意组合双网口,双232串口,双485串口都可以)…

JDBC编程连接MySQL数据库遇到的两个错误

在进行java与MySQL数据库进行连接的时候我遇到了两个报错&#xff0c;在一开始的时候遇到的报错是Access denied for user yulinlocalhost (using password: YES)&#xff0c;此时我在网络上搜索发现是密码出现错误的问题&#xff08;出现该问题确实是密码错误&#xff09;&…

【DevOps】Atlassian插件开发指南

本文以Bamboo插件开发为例&#xff0c;记录一下插件开发过程。 一、简介 Atlassian Bamboo 6.9.1 是一款持续集成和持续交付&#xff08;CI/CD&#xff09;工具&#xff0c;支持使用插件扩展其功能。如果需要开发自己的 Bamboo 插件并添加到 Bamboo 中&#xff0c;则可以参考…

设计模式——享元模式

享元模式 定义 享元模式&#xff08;Flyweight Pattern&#xff09;是池技术的重要实现方式。 使用共享对象可以有效地支持大量的细粒度对象。 优缺点、应用场景 优点 可以大大减少应用程序创建对象的数量&#xff0c;降低程序内存占用。 缺点 提高了系统的复杂度&…

spring-IOC

IOC容器 简介 IoC(Inversion of Control)控制反转&#xff0c;是一种基于面向对象编程法则的设计思想&#xff0c;它设计出的程序具有松耦合、更优良的特点。 IoC容器是Spring框架中重要的核心组件之一&#xff0c;贯穿了Spring从出生到成长的整个过程&#xff0c;Spring通过I…

零基础学习,轻松打造物业服务小程序

现如今&#xff0c;物业服务已经成为了人们生活中不可或缺的一部分。为了更好地满足人们对物业服务的需求&#xff0c;许多企业和个人开始开发物业服务小程序&#xff0c;以便提供更加便捷和高效的服务。然而&#xff0c;对于大多数人来说&#xff0c;搭建一个小程序可能需要一…

智能ai绘画软件帮你用科技点亮创意火花

李明&#xff1a;嘿&#xff0c;你听说过ai绘画软件吗&#xff1f;我最近对数字艺术产生了浓厚的兴趣 王磊&#xff1a;当然&#xff01;ai绘画软件真是太神奇了&#xff01;它可以将抽象的文字描述转换成惊人的艺术作品。 李明&#xff1a;是吗&#xff1f;它们绘制的效果怎…

数据库及数据表的相关操作(一)

目录 概念知识一、管理逻辑库与数据表二、常用数据类型和约束2.1 数字数据类型2.2 字符串数据类型2.3 日期数据类型2.4 字段约束 三、索引运行机制和使用原则3.1 创建索引3.2 添加与删除索引3.3 索引的使用原则 概念知识 关系型数据库&#xff1a; 使用了关系模型的数据库系统&…

深度学习——CNN卷积神经网络

基本概念 概述 卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种深度学习中常用于处理具有网格结构数据的神经网络模型。它在计算机视觉领域广泛应用于图像分类、目标检测、图像生成等任务。 核心思想 CNN 的核心思想是通过利用局部…

MySQL-DQL-聚合函数

目录 聚合函数 注意事项 聚合函数 介绍&#xff1a;将表中的数据作为一个整体&#xff0c;进行纵向计算语法&#xff1a;select 聚合函数&#xff08;字段列表&#xff09; from 表名SUM 求和COUNT 统计数量 具体代码 -- 1.统计该企业员工数量--count -- count(字段) select c…

React Native使用本地修改的三方源码

在 React Native 中&#xff0c;你可以使用本地代码而不是使用第三方库的源码来编译你的应用程序。以下是一般的步骤&#xff1a; 在你的项目目录中创建一个名为overrides&#xff08;或其他适合你的名称&#xff09;的文件夹。 将修复后的 react-native-wheel-pick 源码复制…

Linux内核源代码的目录结构包括部分:

内核核心代码&#xff1a;这部分代码包括内核的各个子系统和模块&#xff0c;如进程管理、内存管理、文件系统、网络协议栈等。这些代码构成了Linux内核的核心功能。 非核心代码&#xff1a;除了核心代码之外&#xff0c;还包括一些非核心的代码和文件&#xff0c;如库文件、固…

uniapp 在app和小程序端使用webview进行数据交互

结论&#xff1a;app端支持比较好可以做到实时传递&#xff0c;微信小程序支持比较差&#xff0c;小程序向url传参只能通过url&#xff0c;url向app传参需要特定时机(后退、组件销毁、分享、复制链接)触发才能收到消息。 以下是代码 app端(需要使用nvue) <template> <…

和chatgpt学架构03-引入UI框架(elment-plus)

目录 1 项目目录及文件的具体作用1.1 App.vue1.2 main.js的作用1.3 main.js什么时候被调用1.4 npm run serve干了什么事情1.5 package.json的作用 2 安装UI框架2.1 安装命令2.2 全局引入 3 启动工程总结 我们已经安装好了我们的vue脚手架&#xff0c;用vscode打开工程目录 要自…

【FPGA】基于C5的第一个SoC工程

文章目录 前言SoC的Linux系统搭建 前言 本文是在毕业实习期间学习FPGA的SoC开发板运行全连接神经网络实例手写体的总结。 声明&#xff1a;本文仅作记录和操作指南&#xff0c;涉及到的操作会尽量细致&#xff0c;但是由于文件过大不会分享文件&#xff0c;具体软件可以自行搜…

Leetcode-每日一题【109.有序链表转换二叉搜索树】

题目 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为高度平衡的二叉搜索树。 本题中&#xff0c;一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。 示例 1: 输入: head [-10,-3,0,5,9]输出: [0,-3,9,-…

VS报错E1696 无法打开类似于stdio.h等头文件的解决办法

VS报错E1696 无法打开类似于stdio.h等头文件的解决办法 我的VS版本是2022的&#xff0c;然后我今天把同事在VS2017上的code&#xff08;一个完整的解决方案&#xff09;从svn上拿过来。结果发现&#xff0c;一大堆E1696的错误。主要表现就是项目中include的一些常用的c语言基础…