当结果错误时从函数返回默认值

2023-12-04

有没有类似的东西?当出现错误时,该快捷方式不是返回函数的结果,而是返回预定义的值?

基本上我想知道是否可以在一行中执行以下操作:

fn index() -> String {
    let temp = some_func("pass"); // some_func returns a Result 
    if temp.is_err() {
        return "No parameters named pass".to_string();
    }
    try_decrypt_data(temp.unwrap())
}

我尝试使用unwrap_or_else(),但这只是返回闭包而不是外部函数。 IE。

try_decrypt_data(params.get("pass").unwrap_or_else(|| return "No parameters named pass".to_string(); )) // This doesn't work

This is kind of可能,但通常不是一个好主意,尤其是在您的示例中(我稍后会解释)。

您不能轻易退货String和做?返回默认值,但您可以定义自己的字符串类型并实现std::ops::Try为了它。注意Try还是不稳定!

让我们看看这是如何工作的:

// Just wrap a string
struct StringlyResult {
    s: String,
}

// Convenience conversion 
impl From<String> for StringlyResult {
    fn from(s: String) -> Self {
        Self { s }
    }
}

// The impl that allows us to use the ? operator
impl std::ops::Try for StringlyResult {
    type Ok = String;
    type Error = String;

    fn into_result(self) -> Result<Self::Ok, Self::Error> {
        if self.s == "No parameters named pass" {
            Err(self.s)
        } else {
            Ok(self.s)
        }
    }

    fn from_error(s: Self::Error) -> Self {
        if s != "No parameters named pass" {
            panic!("wat");
        }
        Self { s }
    }

    fn from_ok(s: Self::Ok) -> Self {
        if s == "No parameters named pass" {
            panic!("wat");
        }
        Self { s } 
    }
}

这样我们就可以实现index()像这样:

fn index() -> StringlyResult {
    let temp = some_func("pass")
        .map_err(|_| "No parameters named pass")?; 
    try_decrypt_data(&temp).into()
}

(Playground 上的完整代码)

所以是的,Try特征使用户能够使用?具有自己类型的运算符。


但是,正如您的示例所示,这是一个糟糕的主意。您可能已经注意到“wat“我上面的代码中的部分。问题是您的 OK 类型已经耗尽了整个类型(该类型的所有实例都是有效的 OK 实例)。

考虑一个函数get_file_size() -> u64。现在这个函数可能会失败(即它无法确定文件大小)。你不能就这么回来0发出发生故障的信号。函数的调用者如何区分函数无法确定文件大小的环境和文件实际上为 0 字节大的环境?

同样,函数的调用者如何区分发生错误的情况和解密后的文本是字面意思的情况"No parameters named pass"?打电话的人不能!这很糟糕。

请注意,有一些类似的东西,虽然没有那么糟糕,但在 Rust 中仍然不是很惯用:get_file_size() -> i64。在这里,我们could return -1发出失败信号。这还好,因为-1永远不可能是有效的文件大小! (换句话说,并非您的类型的所有实例都是有效的 OK 实例)。然而,在这种情况下,仍然很容易忘记检查错误。这就是为什么在 Rust 中,我们总是想使用Result.


为了使错误处理更容易,请考虑使用板条箱failure。这样,您就可以轻松地使用字符串作为错误消息,而无需牺牲程序的类型安全性或健全性。例子:

use failure::{Error, ResultExt};

fn index() -> Result<String, Error> {
    let temp = some_func("pass")
        .context("No parameters named pass")?; 
    Ok(try_decrypt_data(&temp)?)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当结果错误时从函数返回默认值 的相关文章

随机推荐

  • ASP.NET MVC4,视图将旧值返回到控制器

    我是 MVC 和 ASP NET 的新手 我的要求是 我必须第一次在我的视图中显示两条记录 并且我的视图包含一个 交换 按钮 当我按下此按钮时 应该执行控制器的后操作 并且它必须采用原始视图模型 并且需要交换两个记录并且应该呈现相同的视图
  • 在 url 中使用 # 打开模式

    我对这个可能是愚蠢的问题感到抱歉 但我想简单地在 url 中使用 打开模态 因此 如果我调用 www domain com modal1 它将打开已经弹出模式的页面 哦 我正在使用jquery 谢谢你 许多应用程序框架 我偏向backbon
  • 从一组观察结果创建队列式数据框[重复]

    这个问题在这里已经有答案了 我是 R 新手 有一个简单的问题 因为我仍在学习 R 数据操作 管理的风格 我有一段时间内基本临床特征 血压 胆固醇等 观察数据集 每个观察结果都有患者 ID 和日期 但作为单独的行项目输入 像这样的事情 Pat
  • VBA 查找和替换

    我正在使用 Excel VBA 从电子表格生成 Word 文档 作为最后一步的一部分 我想找到所有双段落并将其替换为单段落 基本代码 Dim objWord Dim objDoc Dim objSelection Set objWord C
  • 表视图中的单元格没有响应

    我正在开发一个待办事项列表应用程序 每当我在simulator并尝试打印我的项目array 其他单元格项目被打印 这是我的代码 import UIKit class TodoListViewController UITableViewCon
  • 递归时变量意外更改?

    Context 我目前正在尝试 Reddit 的 r 每日程序员挑战 这个想法是找到 ASCII 迷宫的解决方案 不幸的是 递归的工作方式与我的预期不同 程序检查是否有空间可以移动到当前空间的右侧 左侧 下方或上方 如果存在 则将空间移动到
  • Android 中平板电脑的布局

    我想在 Android 中为平板电脑和手机创建不同的布局 我应该将布局资源放在哪里才能实现这种差异化 我知道这是一个老问题 但为了它 根据文档 您应该像这样创建多个资产文件夹 res layout main activity xml For
  • 如何提高数据严重偏差的养猪工作的绩效?

    我正在运行一个 Pig 脚本 该脚本执行 GROUP BY 和嵌套 FOREACH 由于一两个减少任务 该脚本需要几个小时才能运行 例如 B GROUP A BY fld1 fld2 parallel 50 C FOREACH B U A
  • 像蜗牛一样在路径上进行 SVG 动画

    I have the following SVG and I would like to draw the circles pixel by pixel on the path after moveing It s like when th
  • 使用 JQuery 和 AJAX 刷新 div 以显示 Django 中的新评级

    我是 django 的新手 找不到仅刷新 div 的方法 并且 div 显示了当前的星级评级 我的想法是 用户可以通过单击星星来查看平均评分并对某些内容进行评分 点击后我希望星星显示新的平均评分 而无需刷新整个页面 这是div div di
  • 如何编写最能利用 CPU 缓存来提高性能的代码?

    这听起来像是一个主观问题 但我正在寻找的是特定的实例 您可能遇到过与此相关的实例 如何使代码 缓存有效 缓存友好 更多的缓存命中 尽可能少的缓存未命中 从两个角度来看 数据缓存 程序缓存 指令缓存 即代码中与数据结构和代码构造相关的哪些内容
  • 与 0b 的按位或运算将给定数字转换为负数

    我需要使用按位运算符执行某些操作 假设我们有这个 40 位无符号整数 1071698660929当我申请它时OR运算符和无符号右移运算符我得到这个负整数 Input 1071698660929 gt gt gt 0 0b0 Output 2
  • java.lang.IllegalArgumentException:Jetty ALPN/NPN 尚未正确配置

    Getting java lang IllegalArgumentException Jetty ALPN NPN has not been properly configured 同时使用gRPC google pub sub 发布 消费
  • Mono.Cecil - 如何获取方法体的简单示例

    我一直在寻找新手问题 但找不到简单的例子 谁能给我一个简单的例子 如何将 MethodBody 放入最可用的字符串结果中 喜欢 using Mono Cecil using Mono Cecil Cil namespace my publi
  • Jhipster4,Angular2:如何在html中包含静态图像

    你能帮我在 html 模板中包含静态图像吗 我使用 jhipster 生成器 选择 Angular 2 生成了项目 现在我尝试在组件的 html 模板中包含静态图像 例如导航栏组件 into navbar component html 我将
  • 可以按模型中的属性进行排序吗?

    可以按模型中的属性进行订购吗 class PlayerModel Base tablename players alliances id Column Integer ForeignKey alliances id nullable Tru
  • 如何传递凭据来重命名命令?

    我在 PowerShell 脚本中运行以下命令来简单地重命名计算机 该脚本将由计算机启动脚本 GPO 执行 因此我需要在命令中传递凭据 由于我无法看到脚本在启动时执行时发生了什么 因此我通过以普通用户身份登录时运行脚本来测试它 Get Wm
  • 如何在 PyQt5 GUI 中运行两个无限循环?

    我正在尝试使用 pyqt5 构建 GUI 在 GUI 中 我需要通过 WiFi 从树莓派摄像头传输视频 我需要将游戏手柄输入发送到树莓派 我的代码如下 import sys time math import cv2 import numpy
  • 在 64 位 x 64 位乘法中使用 Karasuba 算法真的有效吗?

    我在 AVX2 上工作 需要计算 64 位 x64 位 gt 128 位加宽乘法 并以最快的方式获得 64 位高位部分 既然AVX2没有这样的指令 那么我使用Karatsuba算法来提高效率和获得速度是否合理 不会 在现代架构中 Karat
  • 当结果错误时从函数返回默认值

    有没有类似的东西 当出现错误时 该快捷方式不是返回函数的结果 而是返回预定义的值 基本上我想知道是否可以在一行中执行以下操作 fn index gt String let temp some func pass some func retu