关于absl::Status和absl::StatusOr<T>的碎碎念

关于absl::Status

用来管理处理上下文错误,在代码中可以更清晰地把错误输出在log中。返回值为absl::Status的函数,有错误时输出各种错误类型,如InternalError,NotFoundError,没有错误时输出absl::OkStatus()。

absl::Status Func(const std::string data_dir){
    if (error 1){
        return absl::InternalError(
                absl::StrCat("Error case 1 at ", data_dir));
    }
    else if (error 2){
        return absl::NotFoundError(
                absl::StrCat("Error case 2 at ", data_dir));
    }
    return absl::OkStatus();
}

absl::StrCat 合并连接两个string

调用返回absl::Status的函数,有两种方式:

1 可以和RETURN_IF_ERROR一起使用,如果Func函数中有错误,外层函数会直接返回Func()的报错信息。

RETURN_IF_ERROR(Func(data_dir)) << "Failed to execute Func.";

2 如果Func(data_dir)在一个循环中,不想在外层函数中直接返回Func()的报错信息,而是跳过或者其他操作,可以用status.ok(),此时返回的是一个bool值,如果Func()没有错误,则返回true,否则返回false。

for (std::string data_dir : data_dirs){
    absl::Status status = Func(data_dir);
    if (!status.ok()){
        // do something with the error
        continue;
    }
}

关于absl::StatusOr<T>

和absl::Status很相似,absl:StatusOr<>适用于有实际返回值的函数

absl::StatusOr<std::string> GetDataDir(){
    if (error){
        return absl::InternalError(
                absl::StrCat("Error getting data dir"));
    }
    return "/path/to/data";
}

调用返回absl::StatusOr<T>的函数,有两种方式:

1 可以和ASSIGN_OR_RETURN一起使用,如果GetDataDir函数中有错误,外层函数会直接返回Func()的报错信息,如果没有错误,则会将GetDataDir()的返回值赋给result变量。

ASSIGN_OR_RETURN(std::string data_dir, GetDataDir());

2 可以用auto result = GetDataDir();或者直接absl::StatusOr<std::string> result = GetDataDir();

一定要在调用 ok()`确认值存在后执行,可以通过 operator*或 operator-> 访问 StatusOr 持有的值(相当于此时result是一个指针),这样是效率且安全的!

In comparison,通过absl::StatusOr::value()结合了上述两个操作:有效性测试(.ok())和值的访问。根据 value() 函数的文档,如果启用了异常,则会抛出 absl::BadStatusOrAccess 异常(该异常可以被捕获,这意味着程序可能不会终止)。如果没有启用异常,则代码将崩溃并输出 LOG(FATAL)。非必要可以避免这样用!

e.g.获取返回值,如果函数有错误,则返回absl::InternalError,否则返回"/path/to/data"。

auto get_data_dir_result = GetDataDir();
if (result.ok()){
    std::cout << *get_data_dir_result;
}

使用RETURN_IF_ERROR和ASSIGN_OR_RETURN,都会在当前函数中报错时立刻退出当前函数,并且返回报错信息到上层函数,因此可以用来管理多层函数的报错信息,更容易在报错信息中定位发生错误的位置。

另外,如果返回absl::Status或absl::StatusOr<T>的函数在一个循环中,我们不想退出循环,直接返回报错,可以用res.ok()去判断instead of RETURN_IF_ERROR和ASSIGN_OR_RETURN!

注意返回absl::Status或absl::StatusOr<T>的函数,在任何情况下不能返回其他类型的值,否则直接编译报错!

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值