本文介绍: 首先,还是再列出Option定义, 它用于任何可能为空的变量。注意在中我们指定x如果不为空时的关联数据变量类型,且使用None时, 也没有使用或者, 这是因为Option类型实在是太常用了,所以Rust默认已经把他们都引入了,不需要再手动导入。判断一个Option类的变量是Some还是None此外, Option还实现了的Trait, 这使得它可以被视为一个长度为0或1的向量,从而可以用for。

Option

首先,还是再列出Option定义, 它用于任何可能为空的变量

enum Option<T&gt; {
	Some(T),
	None,
}

下面的代码展示了如何创建一个空类型

let mut x: Option<i32&gt; = None;

注意在<&gt;我们指定x如果不为空时的关联数据变量类型,且使用None时, 也没有使用use Option::*或者Option::None, 这是因为Option类型实在是太常用了,所以Rust默认已经把他们都引入了,不需要再手动导入。

显式的声明变量为Option枚举类在很多时候也不是必须的, 编译器可以自动根据代码推断,与变量声明初始化类似:

let mut x = None; // 可以推断出x是一个Option类型
x = Some(5); // 可以推断出其中Some变体的关联数据类型为i32

判断一个Option类的变量Some还是None还有一个方便的方法

let mut x = None;
x = Some(5);
x.is_some() // 判断是否为Some变体类型
x.is_none() // 判断是否为None

此外, Option还实现IntoIteratorTrait, 这使得它可以被视为一个长度为0或1的向量,从而可以用for循环进行迭代操作

let mut x = None;
x = Some(5);
x.is_some() // 判断是否为Some变体类型
x.is_none() // 判断是否为None
for i in x {
	println!("{}", i); // 输出 5
}

Result

另一个非常重要且常用的枚举类型Result, 通常用于返回类型,只要返回结果可能是一个正常的值,或者有可能是一个错误,就应该使用Result, 这对我们进行异常错误处理非常有用。Result类型在Rust的内置模块io中特别常见。

Result定义如下:

#[must_use]
enum Result<T, E&gt; {
	Ok(T),
	Err(E),
}

从上面的代码我们可以看出:

正如上文所说,Resultio库中非常常见,因为当我们处理io操作时, 发生错误的几率是很大的, 让我们来看一个例子:

use std::fs::File;

fn main() {
	File::open("foo");
}

在上面的代码中,我们File这个包引入作用域,用其中的open函数尝试打开一个名为foo文件open函数将返回一个Result, 猜猜上面的代码能顺利通过编译吗?请添加图片描述
如图所示,我们得到了一个编译器警告,这只是一个警告,并不会阻止我们通过编译,但是正如上文所说, 我们上面的代码中得到了一个Result, 但没有对它做任何操作就丢弃了它,因此会得到这个告警编译器强烈建议我们要对其进行处理,因为Result结果很可能是一个错误

Result结果处理

unwrap()

那我们应该怎样对Result进行处理呢,最简单的一个方法是使用unwrap():

use std::fs::File;

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

上面的代码中,在res是一个Ok变体类型时,f将被赋值Ok的关联数据, 本例中,应当为foo文件句柄。如果文件无法打开,那res将是一个Err类型的变体,此时unwrap()会造成panic导致程序崩溃退出(崩溃退出也许也是我们某些情况下期望的结果)。

expect()

另一个方法expect()。 它的行为unwrap()基本相同,不同的是, expect()接受一个字符参数,在程序崩溃时,会把字符串打印在崩溃输出中,作为失败的提示

use std::fs::File;

fn main() {
	let res = File::open("foo");
	let f = res.expect("error message");

is_ok()

与Option一样,Result也提供了一些便捷的方法来判断变体类型, is_ok返回一个布尔值,来判断是否是Ok类型的变体:

use std::fs::File;

fn main() {
	let res = File::open("foo");
	if res.is_ok() {
		res.unwrap();
	}
}

上面的代码就保证了只有在操作成功时才对res进行展开,避免程序崩溃

模式匹配处理Result

最好的方法还是使用match模式匹配处理Result, 确保成功和失败的操作都可以被正确处理

use std::fs::File;

fn main() {
	let res = File::open("foo");
	match res {
		Ok(f) =&gt; { do_stuff(f); }
		Err(e) => { handle_err(e); }
	}
}

小结

本章重点介绍了Rust中两种最常见且最有用的枚举类型, 并介绍了对他们进行处理的常见方法。下一章将介绍Rust中另一个重要的设计: 闭包(Closure)。

原文地址:https://blog.csdn.net/m0_37904728/article/details/134664377

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_5327.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注