《Rust权威指南》学习笔记之第9章 错误处理

130 篇文章 4 订阅
9 篇文章 0 订阅

两大类错误:

  • 可恢复错误
    文件未找到等,报告给用户并再次尝试。Result<T, E>
  • 不可恢复错误
    bug,尝试访问超过数组结尾的位置等。panic!

不可恢复错误与panic!

panic!宏执行时打印出一段错误提示信息,展开并清理当前的调用栈,然后退出程序。

panic中的栈展开与终止
panic发生时,程序会默认开始栈展开,反向遍历所有调用函数,并清理函数中的错误,需要二进制中存储许多额外信息。可以立即终止程序,而不进行任何清理,使用内存由操作系统回收。通过配置Carog.toml文件,减小二进制包。
[profile.release]
panic = ‘abort’

fn main() {
	panic!("crash and burn");
}

panic!中产生回溯信息

fn main() {
	let v = vec![1, 2, 3];
	v[99];	//缓冲区溢出(buffer overread)
}

获得回溯信息,必须启用调试符号 (debug symbol),cargo build或cargo run不附带–release标志。

RUST_BACKTRACE=1 cargo run

可恢复错误与Result

enum Result<T, E> {
	OK(T),
	Err(E),
}
use std::fs::file;

fn main() {
	let f = File::open("hello.txt");
	//let f: u32 = File::open("hello.txt");	//报错查看类型
}
use std::fs::file;

fn main() {
	let f = File::open("hello.txt");

	let f = match f {
		Ok(file) => file,
		Err(error) => {
			panic!("There was a problem opening the file: {:?}", error);
		},
	}
}

匹配不同错误

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("hell.txt") {
				OK(fc) => fc,
				Err(e) => panic!("Tried to create file but there was a problem: {:?}", e),
			},
			other_error => panic!("There was a problem opening the file: {:?}", other_error),
		},
	}
}
use std::fs::File;
use std::io::ErrorKind;

fn main() {
	let f = File::open("hello.txt").map_err(|error| {
		if error.kind() == ErrorKind::NotFound {
			File::create("hell.txt").unwrap_or_else(|error| {
				panic!("Tried to create file but there was a problem: {:?}", error);
			});
		} else {
			panic!("There was a problem opening the file: {:?}", other_error);
		}
	});
}

失败时触发panic的快捷方式:unwrap和expect

unwrap方法,Result返回值是Ok时,返回Ok内值;Error时,调用panic。

use std::fs::file;

fn main() {
	let f = File::open("hello.txt").unwrap();
}

expect方法,在unwrap基础上指定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;

fn read_username_from_file() -> Result<String, io::Error> {
	let f = File::open("hello.txt");
	
	let mut f = match f {
		Ok(file) => file,
		Err(e) => return Err(e),
	}
	
	let mut s = String::new();

	match f.read_to_sttring(&mut s) {
		Ok(_) => Ok(s),
		Err(e) => Err(e),
	}
}

传播错误的快捷方式:?运算符

?放于Result后,Result值是Ok时,返回Ok中的值并继续执行程序;Err时,返回并退出程序。

?运算符接收的错误值会隐式地被from函数处理,定义于标准库的From trait中,用于错误类型间转换(传入错误类型转换为当前函数返回错误类型)。

use std::io;
use std::io::Read;
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
	let mut f = File::open("hello.txt")?;	
	let mut s = String::new();
	f.read_to_sttring(&mut s)?;
	Ok(s)
}
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_sttring(&mut s)?;
	Ok(s)
}
use std::io;
use std::fs;

fn read_username_from_file() -> Result<String, io::Error> {
	fs.read_to_sttring("hello.txt")
}

?运算符只能被用于返回Result的函数

use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>> {
	let f = File::open("hello.txt")?;	
	Ok(())
}

要不要使用panic!

不可恢复用panic!,定义可能失败的函数(失败可预期)优先考虑使用Result。
示例、原型和测试使用panic!。

use std::net::IpAddr;

let home: IpAddr = "127.0.0.1".parse().unwrap();

创建自定义类型进行有效性验证

loop {

	let guess: i32 = match guess.trim().parse() {
		Ok(num) => num,
		Err(_) => continue,
	};

	if guess<1 || guess>100 {
		println!("The secret number will be between 1 and 100.");
		continue;
	}

	match guess.cmp(&secret_number) {

	}
}
pub struct Guess {
	value: i32,
}

impl Guess {
	pub fn new(value: i32) -> Guess {
		if value<1 || value>100 {
			panic!("Guess number must be between 1 and 100, got {}.", value);
		}
	}
	
	pub fn value(&self) -> i32 {	//读取接口(getter)
		self.value
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Rust权威指南是一本深入介绍Rust编程语言的权威性书籍。这本书主要介绍Rust语言的基本语法和特性,包括Rust的所有关键字、数据类型、函数、模块、宏、”生命周期”、所有权等重要概念的详细解释和使用方法。 这本书由Rust社区知名的开发者Steve Klabnik和Carol Nichols撰写,是Rust开发者及其他想要学习Rust编程语言的程序员的必读之作。书中详细介绍了Rust的语法规则和特性,如何编写高质量、高性能的Rust代码,以及如何使用Rust来进行并发编程和系统级编程。 通过阅读本书,读者能够了解Rust的核心概念,如所有权、生命周期和借用,以及如何使用Rust的工具链进行开发。在本书的后半部分,作者通过实践案例和示例向读者展示了如何使用Rust来编写高效、可靠的程序。 总的来说,Rust权威指南是一本非常实用且详尽的Rust编程语言指南,对于想要学习Rust编程语言的读者非常有益。不仅提供了基础知识方面的介绍,还给读者提供了诸如性能优化等高级内容的指导。同时,本书也适合那些已经有一定Rust编程经验的读者,它们可以通过本书深入了解Rust语言内部之间的联系。 ### 回答2: 《Rust权威指南》是一本针对Rust编程语言的详细讲解和指导的权威指南。该书由Rust的核心开发人员编写,涵盖了Rust语言的基本概念、语法、数据类型、内存管理、并发编程、错误处理、泛型、宏等方面,旨在帮助读者全面深入地学习和理解Rust语言。 该书内容广泛,详细全面,适合初学者和有经验的开发人员。书中每一都有大量的代码示例,并附有解释和注释,易于理解。书中还介绍了Rust的生态系统和常用开发工具,如包管理器Cargo、测试框架等。 此外,《Rust权威指南》还强调了Rust语言的安全性和性能优势。Rust通过静态类型检查、所有权系统、借用规则等机制,大大减少了程序运行时的内存安全问题。同时,Rust的设计和实现也使得其具有与C++类似的性能优势。 总的来说,《Rust权威指南》是一本权威性强、内容深入的Rust编程指南。对于想要学习Rust编程语言的开发人员来说,这本书绝对是一本值得购买和阅读的好书。 ### 回答3: 《Rust权威指南》是一本全面介绍Rust语言的书籍,该书由Rust中文社区的翻译小组翻译而成。这本书详细讲解了Rust语言的语法、基础知识、数据类型、控制流、函数、模块、生命周期、所有权系统等内容,涵盖了Rust语言的各个方面。 这本书的特点在于其权威性和全面性。作为Rust语言的权威指南,该书不仅涵盖了Rust语言的基础知识,还深入讲解了Rust语言的高级特性,如内存管理、安全性、并发等方面。此外,书中还包括了大量的实例和案例,可以帮助读者更深入地理解Rust语言。 对于初学者来说,该书可以作为Rust语言的入门指南。对于已经掌握了Rust语言基础知识的读者来说,本书也可以作为进一步深入学习和实践Rust语言的指南。此外,该书还提供了完整的API文档和Rust语言的标准规范,方便读者进行参考和查阅。 总之,《Rust权威指南》是一本全面、详细、权威Rust语言指南,适合Rust语言的初学者和进阶者。读者可以通过该书深入了解Rust语言并掌握其应用,提高自己的编程能力和实践经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值