在GO中,通常会通过函数返回错误。如果调用函数时返回错误,则必须对其进行处理。一旦处理了错误,如果资源不处理错误,就很容易犯错误。LET查看如何使用defer在实际程序中简化我们的程序。
首先,我们查看一个不使用defer语句关闭资源的示例。我们实现复制文件的副本。我们还管理文件的描述符的关闭,因为一旦打开了 *os.file并准备好读写,它必须使用关闭功能来关闭。最后,在功能结束时,我们将使用同步方法来刷新文件系统的缓冲区,以便将磁盘上的内容强加于使副本耐用。以下是特定的实现:
①开源文件
②检查是否是目录
③创建目标文件
④将源文件复制到目标文件
⑤刷新文件系统缓冲区
注意:关闭*os.file将返回错误。管理章节,我们将看到如何在延期声明中优雅地处理错误。
此实现可以工作。我们打开源文件,检查它是否是目录,然后处理复制逻辑。但是,我们注意到一些模板代码:
在代码中,源文件和目标文件必须在最后关闭,这使我们的代码非常容易犯错。不幸的是,GO提供了通过延期关键字解决问题的解决方案,如图2.1:
当函数返回时,延期函数被称为。即使在主函数慌张或意外终止时也可以执行defer函数。按下defer推入堆栈。当主函数返回时,defer函数从堆栈中弹出(the stack(进步后的高级顺序。此处,C()将首先称为B(),最后是A()。
注意:延期呼叫的时间是函数返回时,而不是在退出块时。如下:
让我们回到CopyFile函数的示例,并使用延期关键字再次实现:
①延迟致电src.close()
②延迟致电dst.close()
在此版本的实现中,我们通过使用延期关键字删除了重复的密闭调用。这使该功能更轻松,易于阅读。我们不必在每个代码路径的末尾关闭SRC和DST,因此,犯错误并不容易。
延期语句通常与成对出现的操作函数一起使用,就像打开/关闭,连接/断开连接以及锁/解锁功能一样,以确保在所有情况下都可以发布资源。
这是使用Sync.mutex的另一个示例:
sutex锁
②在延期语句中解锁
我们使用s.mutex.lock函数锁定互斥X,并在延期中调用s.mutex.unlock()函数的配对操作。
注意:如果我们必须实现前和后操作,例如Mutex锁定/解锁而不返回任何值,我们也可以这样实施:
①它将立即执行s.lockunlock(),但是它将延迟执行s.lockunlock()()()
延迟函数调用是s.lockunlock()(),而不是s.lockunlock()。因此,s.lockunlock()部分将立即执行(s.mutex.lock),但返回的闭合将延迟(s.mutex.unlock())。它添加了一些语法糖,并使用一系列代码来处理功能中的前/后方操作,有时非常方便。如果使用此型号s.lockunlock()()带有两组括号,这可能会非常混乱,具体取决于您的团队资格。
重建代码时,我们需要注意可能的影响。例如,当我们需要将包含延期调用的主函数拆分为多个函数时,在这种情况下,一旦执行了该应用程序,defer语句就不会执行executetransfer:
①程序结束延期呼叫,将执行它
②当延期呼叫完成操作函数时,将执行它
在这里,我们通过重建消费者介绍了一个错误。由于处理程序器功能结束后,将执行Consumer.Close()。它看起来像是一个简单的注释,但是当我们必须重建大量代码时,有时候很容易,这很容易忽略延期陈述。
同时,有必要注意以前的GO 1.14。延期语句不在美国。内部对联是一种优化技术,可以直接在呼叫函数中编译函数呼叫。这就是为什么在具有关键因素的某些项目中很少使用延期关键字。版本,可以通过内部耦合来优化延期语句。
简而言之,延期可以避免僵化的守则,并降低忘记释放资源的风险,例如释放资源,断开连接链接,mutex Unlocking等。
作者:Yudotyang