前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Rust笔记] `?`操作符是如何“抽象”错误类型与“短路”函数的

[Rust笔记] `?`操作符是如何“抽象”错误类型与“短路”函数的

作者头像
MikeLoveRust
发布2022-06-10 15:11:39
1.5K0
发布2022-06-10 15:11:39
举报

?操作符是如何“抽象”错误类型与“短路”函数的

  • 首先,?操作符是被用来勾连·函数体内Result<T, E1>·与·函数返回值类型Result<T, E2>·的【语法糖】。它的“去糖”展开式如下:
  • 其次,就功能而言,?操作符相当于“温和版”的Result::unwrap()成员方法。即,
    • 先将?操作符前Result<T, E1>中的E1·类型转换·为【函数】返回值类型Result<T, E2>中的E2
    • 再“短路”当前执行函数和退出函数。注意:
    • 这一步要求E2实现了From<E1> trait
    • 这里是结束当前执行函数,而不像Result::unwrap()“粗暴”地结束当前执行线程。要不,怎么说?“温和”呢!
    • 若开启了Cargo.toml [package] panic = "abort",后者Result::unwrap()还会造成内存泄露。
    • 成功线 —— 取出?操作符前Result<T, E1>的内部值T和作为表达式的返回结果。
    • 失败线 ——
  • 接着,重点来了。【函数】返回值类型Result<T, E2>中的E2是一个“同时兼容于所有其它错误类型的、统一的【“抽象”错误类型】”。按其“抽象”方式分为如下两种情况: 上面两种方式都能把·从函数体内抛出的·不同类型的·错误,经由?操作符,收拢于“一处”。 在这里,我把【类型转换】称为“抽象”是否有些牵强呀? 毕竟,其基础原理与oop中的【抽象】不太一样。
    • 前者的“一处”是(类型转换至)一个具体类型 —— 静态分派;
    • 后者的“一处”是(类型转换至)trait Object —— 动态分派。
    • E2就是Box<dyn Error>,因为【标准库】给Box<T>实现了From<Error> trait。其本质也是【类型转换】。
    • 这个,我一直以来使用得比较多。
    • E2是实现了From<E1> trait的任何具体类型。即,E1可被类型转换为E2类型。【类型转换】是其底层机制。
    • 而且,不强制要求E2再显示地实现Error trait
    • 这一块是我曾经的知识盲点
    • 静态分派(抽象):[例程1]
    • 动态分派(抽象):[例程2]
  • 最后,借助于Option::ok_or(_)Option::ok_or_else(FnOnce)Option<T>也能与?操作符搭配使用。即,[例程3]
    • 先将Option<T>类型转换为Result<T, E>
    • 再搭配?操作符语法糖

例程请查看https://rustcc.cn/article?id=98cc1ebf-a624-4e65-8547-66a03c7160e0

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ?操作符是如何“抽象”错误类型与“短路”函数的
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档