我在读go语言的defer条声明.它允许您指定函数结束时要执行的操作.例如,如果您有一个文件指针或资源,而不是用每个可能的返回路径写入free/delete,您只需要指定一次defer函数.

看起来类似于最终会出现C++(What is standard defer/finalizer implementation in C++?, Will there be standardization of scope guard/scope exit idioms?),直到那时,有什么意外的事情发生在它的析构函数进行回调的对象上吗?它看起来像destructor order for local variables is sane,而且它也能很好地处理异常,尽管可能不会在信号上退出.

下面是一个示例实现.有什么问题吗?

#include <iostream>
#include <functional>
using namespace std;

class FrameExitTask {
    std::function<void()> func_;
public:
    FrameExitTask(std::function<void()> func) :
    func_(func) {
    }
    ~FrameExitTask() {
        func_();
    }
    FrameExitTask& operator=(const FrameExitTask&) = delete;
    FrameExitTask(const FrameExitTask&) = delete;
};

int main() {
    FrameExitTask outer_task([](){cout << "world!";});
    FrameExitTask inner_task([](){cout << "Hello, ";});
    if (1+1 == 2)
        return -1;
    FrameExitTask skipped_task([](){cout << "Blam";});
}

yields :Hello, world!

推荐答案

这个已经存在了,它被称为作用域保护.请看这个精彩的演讲:https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C.这使您可以轻松创建要在退出时调用的任意可调用对象.这是较新的版本,它最初是在围棋出现之前很久就开发出来的.

一般来说,它工作得很好,但我不确定你所说的处理异常是什么意思.从一个必须在作用域出口调用的函数中抛出异常是一个混乱.原因是:当抛出异常(而不是立即捕获)时,当前作用域退出.所有析构函数都将运行,异常将继续传播.如果其中一个析构函数抛出,你会怎么做?你现在有两个活的例外.

我想语言可以try 用几种方法来处理这个问题,但是这非常复杂.在C++中,抛出析构函数被认为是一个好主意的情况非常少见.

Go相关问答推荐

golang.org/x/oauth2 oauth2.Config.Endpoint.TokenURL mock:缺少access_token

golang有int32溢出吗?

如果values.yaml文件中不存在某个属性,如何返回默认的FALSE?

正确使用pgtype的方法

通过渠道和goroutines增值1000倍

Makefilego version和read命令

如何修复proxyconnect tcp:tls:第一条记录看起来不像tls握手

Go:拆分一个由逗号分隔的键/值对字符串,并在给定的键/价值对中嵌入可能的逗号

确定果朗CSV行中的字节数

如何在 zap 记录器库中使用自定义时间函数

如何为ANTLR4目标Go调试监听器

为什么我只收到部分错误而不是我启动的 goroutines 的所有错误?

从Go中的随机日期开始以天为单位获取时间

Go:从 ssl 证书中获取 'subject/unstructeredName' 的值

如何编写一个以字符串或错误为参数的通用函数?

没有堆栈跟踪的 go 程序崩溃是什么意思?

将 Golang Gin 与 AWS Lambda 和无服务器与代理路径一起使用

如何在 GORM 中迭代一个 int 数组

分配空切片而不引用其类型?

Go 1.18 泛型如何使用接口定义新的类型参数