千家信息网

Result/Option/unwrap/的概念是什么

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,本篇内容主要讲解"Result/Option/unwrap/的概念是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Result/Option/unwr
千家信息网最后更新 2025年12月02日Result/Option/unwrap/的概念是什么

本篇内容主要讲解"Result/Option/unwrap/的概念是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Result/Option/unwrap/的概念是什么"吧!

1、Option - 可空变量

虽然Rust中有null的概念,但是使用null并不是Rust中常见的模式。假设我们要写一个函数,输入一种手机操作系统的名称,这个函数就会返回其应用商店的名称。如果传入字符串iOS,该函数将返回App Store;如果传入字符串android,那么该函数将返回Play Store。任何其他的输入都被视为无效。

在大多数开发语言中,我们可以选择返回null或字符串invalid来表示无效的结果,不过这不是Rust的用法。

地道的Rust代码应该让该函数返回一个Option。Option或更确切的说Option是一个泛型,可以是SomeNone(为了便于阅读,后续文章中将省略类型参数T)。Rust将SomeNone称为变体(Variant) -- 这一概念在其他语言中并不存在,因此我也不 去定义到底什么是变体了。

在我们的示例中,正常情况下函数将返回包裹在Some变体中的字符串常量App Store或Play Store。而在非正常情况下,函数将返回None。

fn find_store(mobile_os: &str) -> Option<&str> {    match mobile_os {        "iOS" => Some("App Store"),        "android" => Some("Play Store"),        _ => None    }}

要使用find_store(),我们可以用如下方式调用:

fn main() {    println!("{}", match find_store("windows") {        Some(s) => s,        None => "Not a valid mobile OS"    });}

完整的代码如下:

fn find_store(mobile_os: &str) -> Option<&str> {    match mobile_os {        "iOS" => Some("App Store"),        "android" => Some("Play Store"),        _ => None    }}fn main() {    println!("{}", match find_store("windows") {        Some(s) => s,        None => "Not a valid mobile OS"    });}

2、Result - 包含错误信息的结果

Result,或者更确切地说Result,是和Rust中的Option相关的概念,它是一个加强版本的Option。

Result可能有以下结果之一:

  • Ok(T):结果为成员T

  • Err(E):结果为故障成员E

与之前我们看到Option可以包含Some或None不同,Result中包含了错误相关信息,这是Option中所没有的。

让我们看一个函数实例,它返回一个Result。该函数摘自用于解析JSON字符串的serde_json库,其签名为:

pub fn from_str<'a, T>(s: &'a str) -> Result where    T: Deserialize<'a>,

假设我们要解析如下的字符串:

let json_string = r#"    {        "name": "John Doe",        "age": 43,        "phones": [            "+44 1234567",            "+44 2345678"        ]    }"#;

目标是解析为Rust的一个person结构对象:

#[derive(Serialize, Deserialize)]struct Person {    name: String,    age: u8,    phones: Vec,}

解析过程的Rust代码如下:

let p:Person = match serde_json::from_str(json_string) {    Ok(p) => p,    Err(e) => ... //we will discuss what goes here next };

正常情况下可以得到期望的结果。不过假设在输入的json_string中有一个笔误,这导致程序运行时将执行Err分支。

当碰到Err时,我们可以采取两个动作:

  • panic!

  • 返回Err

3、unwrap - 故障时执行panic!

在上面的示例中,假设我们期望panic!:

let p: Person = match serde_json::from_str(data) {        Ok(p) => p,        Err(e) => panic!("cannot parse JSON {:?}, e"), //panic    }

当碰到Err时,上面的代码panic!就会崩掉整个程序,也许这不是你期望的。我们可以修改为:

let p:Person = serde_json::from_str(data).unwrap();

如果我们可以确定输入的json_string始终会是可解析的,那么使用unwrap没有问题。但是如果会出现Err,那么程序就会崩溃,无法从故障中恢复。在开发过程中,当我们更关心程序的主流程时,unwrap也可以作为快速 原型使用。

因此unwrap隐含了panic!。虽然与更显式的版本没有差异,但是危险在于其隐含特性,因为有时这并不是你真正期望的行为。

无论如何,如果我们需要调用panic!,代码如下:

use serde::{Deserialize, Serialize};use serde_json::Result;#[derive(Serialize, Deserialize)]struct Person {    name: String,    age: u8,    phones: Vec,}fn typed_example() -> Result<()> {    //age2 is error on purpose    let data = r#"        {            "name": "John Doe",            "age2": 43,            "phones": [                "+44 1234567",                "+44 2345678"            ]        }"#;    let p:Person = serde_json::from_str(data).unwrap();    println!("Please call {} at the number {}", p.name, p.phones[0]);    Ok(())}fn main() {    match typed_example() {        Ok(_) => println!("program ran ok"),        Err(_) => println!("program ran with error"),    }}

4、? - 故障时返回Err对象

当碰到Err时,我们不一定要panic!,也可以返回Err。不是每个Err都是不可恢复的,因此有时并不需要panic!。下面的代码返回Err:

let p: Person = match serde_json::from_str(data) {        Ok(p) => p,        Err(e) => return Err(e.into()),};

?操作符提供了一个更简洁的方法来替换上面的代码:

let p:Person = serde_json::from_str(data)?;

这时完整的Rust程序代码如下:

use serde::{Deserialize, Serialize};use serde_json::Result;#[derive(Serialize, Deserialize)]struct Person {    name: String,    age: u8,    phones: Vec,}fn typed_example() -> Result<()> {    //age2 is error on purpose    let data = r#"        {            "name": "John Doe",            "age2": 43,            "phones": [                "+44 1234567",                "+44 2345678"            ]        }"#;    let p: Person = serde_json::from_str(data)?;    println!("Please call {} at the number {}", p.name, p.phones[0]);    Ok(())}fn main() {    match typed_example() {        Ok(_) => println!("program ran ok"),        Err(e) => println!("program ran with error {:?}", e),    }}

5、使用unwrap和?解包Option

就像我们可以使用unwarp和?来处理Result,我们也可以使用unwrap和?来处理Option。

如果我们unwrap的Option的值是None,那么程序就会panic!。示例如下:

fn next_birthday(current_age: Option) -> Option {        // If `current_age` is `None`, this returns `None`.        // If `current_age` is `Some`, the inner `u8` gets assigned to `next_age` after 1 is added to it    let next_age: u8 = current_age?;    Some(format!("Next year I will be {}", next_age + 1))}fn main() {  let s = next_birthday(None);  match s {      Some(a) => println!("{:#?}", a),      None => println!("No next birthday")  }}

到此,相信大家对"Result/Option/unwrap/的概念是什么"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

函数 代码 概念 字符 字符串 程序 结果 故障 面的 期望 输入 变体 情况 示例 这不 信息 内容 名称 对象 成员 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京有竹居网络技术有限公 淘宝服务器有哪几个 数据库备份导入数据库 电子刊数据库英语怎么说 梦幻2008服务器一直连不上 软件开发工程师招聘青岛 创建一个数据库实例 百色市加强网络安全 集团公司网络安全知识答题答案 数据库文档的英文 网络工作站和服务器有什么区别 数据库取数据进行分析 网络安全隐私宣传 嘉兴软件开发驻场哪家可靠 绝地求生端游显示服务器满 广东光纤网络技术开发商家 石家庄专业软件开发公司 电子商务与数据库系统 PHP实验八mysql数据库 银行网络安全培训心得 软件开发小项目介绍 软件开发用哪款linux 海南云兆网络技术有限公司旗下游戏 河南青柚网络技术有限公司 idc如何快速开发云数据库 天津汽车控制器底层控制软件开发 临沂服务器管理系统公司 金牛区网络安全宣传 服务器开启了自动续费多久能使用 安徽5g专业服务器机柜云空间
0