在循环中延迟释放资源的正确方法?

2024-01-09

我需要在循环中对数据库进行 SQL 查询:

for rows.Next() {

   fields, err := db.Query(.....)
   if err != nil {
      // ...
   }
   defer fields.Close()

   // do something with `fields`

}

什么会更好:保持原样或移动defer循环后:

for rows.Next() {

   fields, err := db.Query(.....)
   if err != nil {
      // ...
   }

   // do something with `fields`
}

defer fields.Close()

或者是其他东西 ?


延迟函数的执行不仅被延迟,延迟到周围函数返回的那一刻,即使封闭函数突然终止,它也会被执行,例如恐慌。规格: 延迟声明: https://golang.org/ref/spec#Defer_statements

“defer”语句调用一个函数,该函数的执行被推迟到周围函数返回的那一刻,因为周围函数执行了返回声明 https://golang.org/ref/spec#Return_statements,到达其末端函数体 https://golang.org/ref/spec#Function_declarations, 或者因为对应的 goroutine 是惊慌失措 https://golang.org/ref/spec#Handling_panics.

每当您创建一个值或一个提供正确关闭/处置它的方法的资源时,您应该始终使用defer声明以确保即使您的其他代码发生恐慌也能释放它,以防止泄漏内存或其他系统资源。

确实,如果您在循环中分配资源,则不应简单地使用defer,因为这样就不会释放资源尽早 and should(在每次迭代结束时),仅在for语句(仅在所有迭代之后)。

您应该做的是,如果您有一个分配此类资源的代码片段,请将其包装在一个函数中(匿名函数或命名函数),并且在该函数中您可以使用defer,并且一旦不再需要资源就会被释放,重要的是即使你的代码中有一个可能会出现恐慌的错误。

Example:

for rows.Next() {
    func() {
        fields, err := db.Query(...)
        if err != nil {
            // Handle error and return
            return
        }
        defer fields.Close()

        // do something with `fields`
    }()
}

或者如果放入命名函数中:

func foo(rs *db.Rows) {
    fields, err := db.Query(...)
    if err != nil {
        // Handle error and return
        return
    }
    defer fields.Close()

    // do something with `fields`
}

并称其为:

for rows.Next() {
    foo(rs)
}

另外,如果您想在第一个错误时终止,您可以从以下位置返回错误foo():

func foo(rs *db.Rows) error {
    fields, err := db.Query(...)
    if err != nil {
        return fmt.Errorf("db.Query error: %w", err)
    }
    defer fields.Close()

    // do something with `fields`
    return nil
}

并称其为:

for rows.Next() {
    if err := foo(rs); err != nil {
        // Handle error and return
        return
    }
}

另请注意Rows.Close() https://golang.org/pkg/database/sql/#Rows.Close返回一个错误,当使用调用时defer被丢弃。如果我们想检查返回的错误,我们可以使用像这样的匿名函数:

func foo(rs *db.Rows) (err error) {
    fields, err := db.Query(...)
    if err != nil {
        return fmt.Errorf("db.Query error: %w", err)
    }
    defer func() {
        if err = fields.Close(); err != nil {
            err = fmt.Errorf("Rows.Close() error: %w", err)
        }
    }()

    // do something with `fields`
    return nil
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在循环中延迟释放资源的正确方法? 的相关文章

  • vscode 中的调试不会在断点处停止,调试器启动时显示“无法找到文件...”

    乌班图 vscode 1 62 1 去1 17 3 vscode go 扩展 v0 29 0 深入研究 v1 7 1 我是 vscode 和 Go 的新手 我有多年在 Eclipse 中调试 Java 应用程序的经验 我构建了一个小型多模块
  • 应该尝试...catch进入循环内部还是外部?

    我有一个看起来像这样的循环 for int i 0 i lt max i String myString float myNum Float parseFloat myString myFloats i myNum 这是一个方法的主要内容
  • 当变量更新时动态刷新模板的一部分golang

    在Golang中 当变量更新时可以刷新模板的一部分吗 例如 我们可以在 Angular js 中找到这一点 基本上在我的代码中 我通过 ajax 中的邮政编码查找地址 它显示我找到的该邮政编码的用户列表 Here is a sample o
  • 使用 CodeIgniter 在循环中加载视图是一种不好的做法

    我刚刚开始使用 CodeIgniter 想知道如果我将这样的代码放入循环中 它会减慢速度吗 data title the title data content blah blah blah this gt load gt view resu
  • 如何循环遍历关联数组并获取密钥?

    我的关联数组 arr array 1 gt Value1 2 gt Value2 10 gt Value10 使用以下代码 v充满了 arr的价值观 foreach arr as v echo v Value1 Value2 Value10
  • Java 字节码中循环的检测 - 区分后沿类型

    背景 在提出问题之前 我想声明我已检查以下链接 识别java字节码中的循环 https stackoverflow com questions 6792305 identify loops in java byte code Java 字节
  • 无法连接到代理“证书由未知机构签名”

    我正在尝试通过 Kubernetes 部署上的 cloudsql proxy 容器连接到 CloudSQL 实例 我已安装 cloudsql 凭据以及值GOOGLE APPLICATION CREDENTIALS set 但是 我的日志中仍
  • 如何循环遍历表并保持顺序?

    我得到了下表 local a 12 30 24 60 60 year 30 24 60 60 month 24 60 60 day 60 60 hour 60 minute 1 second 但是 当我对它进行配对循环并打印 key val
  • 使用 jQuery .each 迭代关联数组

    可能对这个问题最有影响的因素是我现在非常困 我有一个数组 我启动它 var cells 然后我在其中放入一些值 jQuery 对象 例如 td each function var td this cells td attr id td 现在
  • 视频第一帧

    我正在创建一个单页应用程序 后端使用 Golang 前端使用 javascript 我想找到一种使用 Golang 获取视频第一帧的方法 首先 我将 mp4 视频文件上传到服务器 它保存在服务器上 有没有办法使用 Golang 获取该视频的
  • 在这个使用泛型的初学者 java 示例程序中,“:”在做什么?

    好吧 我需要帮助理解一些事情 我理解 是如何一起使用的 但是阅读一些 Java 入门资料后 我发现这种情况在一些地方出现 最近的是这个 public static u void fillBoxes U u List u
  • 在 IntelliJ IDEA 中运行。多个文件和错误未定义:数据

    我想使用 IntelliJ IDE 社区版编写代码GO Go语言 我安装了正确的插件 并安装了构建应用程序所需的所有工具 我的应用程序包含以下两个文件 每个都在目录中 事件服务器 Main go Data go 如果我想使用 Run Ctl
  • 如何在C#中执行Go函数

    有没有办法从 C 执行 Go 函数 例如 对于 Python 我会使用 Ironpython 我知道我可以生成一个进程来执行 Go 脚本 但如果可能的话 我真的不想回退到这样的解决方案 Google 搜索没有显示任何内容 那么有什么方法可以
  • 根据javascript中对象数组中的id替换特定对象

    我有一系列像这样的对象 var books id 1 name Name of the wind year 2015 rating 4 5 author 2 现在我有一个函数 editBooks 它要求用户提供 id 并用用户给出的值替换具
  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 如何在 Golang 中将 []byte XML 转换为 JSON 输出

    有没有办法在 Golang 中将 XML byte 转换为 JSON 输出 我有以下功能body is byte但我想在一些操作之后将此 XML 响应转换为 JSON 我试过了Unmarshal in xml打包没有成功 POST func
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par
  • Golang中如何获得100%的代码覆盖率? [复制]

    这个问题在这里已经有答案了 我无法获得 100 的代码覆盖率 因为我无法在 Golang 中测试 Fatals 我发现了一些问答 包括this one https stackoverflow com questions 30688554 h
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 我应该避免在 golang 中使用单例包吗?

    现在我有一个包裹store包含以下内容 package store var db Database func Open url string error open db connection func FindAll model inter

随机推荐

  • 项目中尚未使用旧版 People API

    我在调用 google 登录 API 时遇到错误 错误是 旧版 People API 之前未在项目 中使用过或已被禁用 但人员 API 已启用 如何解决这个错误 这是我的 google api url 这足以解决我的问题 if empty
  • 如何在 ruby​​ 中清理格式错误的 xml

    我在整理从以下网站返回的格式错误的 XML 代码时遇到问题SEC 的 edgar 数据库 http www sec gov edgar shtml 由于某种原因 他们形成了可怕的 xml 包含任何类型字符串的标签都不是封闭的 它实际上可以在
  • Qt 5 无法部署在 SnowLeopard 上

    我遇到的问题是我的应用程序无法在 10 6 Snow Leopard 上运行 我使用这些参数进行编译 qmake LSPRO pro r spec macx clang CONFIG release CONFIG x86 64 在我的 Pr
  • WatiN:CurrentThread 需要将其 ApartmentState 设置为 ApartmentState.STA 才能自动化 Internet Explorer

    我正在从 C Windows 服务调用 WatiN 当我调用 WatiN 时 它抛出以下异常 CurrentThread 需要将其 ApartmentState 设置为 ApartmentState STA 才能自动化 Internet E
  • 同一线程上的 WebView 方法错误

    我有一个 android 程序 Webview 中的 Java html 我可以从 javascript 调用 Java 代码 但相反的方式停止工作 在 Eclipse 中更新后 这就是我想做的 制作一个网络视图 有效 在 javascri
  • SimpleXML 如何在节点中添加子节点?

    当我打电话时 addChild actor John Doe 这个孩子是最后添加的 有没有办法让这个新孩子成为第一个孩子 正如前面提到的 SimpleXML 不支持这一点 因此您必须使用 DOM 我的建议如下 使用您需要在程序中使用的任何内
  • ios - 从手指移动画笔

    我想在我的 iPad 应用程序中画画 如下图所示 in my app i have placed a image and while moving the finger touch movement i am repeating the i
  • 如何从列表中获取特定项目?

    我有一个案例类别的列表 我想从列表中获取特定项目 I do myList filter id myobject id 0 当filter实际上返回一些东西 但是 当过滤器不返回任何内容时 我会得到索引越界异常 scala gt case c
  • 为什么需要使用 EntryPoint 属性定义 DLLImport

    在经历的同时SWig http www swig org 生成的包装器中 我发现 PInvoke 没有定义任何入口点 但有些地方确实有入口点 那么它们之间有什么区别呢 什么时候需要定义 EntryPoint 什么时候不需要 定义无Entry
  • 按钮图像距离按钮顶部太远;太靠近按钮底部

    我正在 VB NET 2005 中开发 Windows 窗体 我想要一些带有图像的按钮 我说的是普通的 普通的 System Windows Forms Button 我已按照我想要的方式设置了所有内容 但图像在按钮上显示得太低 因此图标的
  • 如何打包不是使用 vagrant up 命令创建的现有虚拟机?

    我安装了 VirtualBox 然后在其中安装了 Ubuntu 12 10 Server Base OS 我在里面安装了各种php包和其他包 我的朋友推荐我使用 Vagrant 这样我就可以轻松地与我的队友分享我的设置 因为我当前的 Vir
  • pygame全屏模式退出

    我正在运行这个小程序 它以全屏模式将图像加载到屏幕上 但是一旦加载 程序将不会通过任何组合键退出 我最终不得不重置计算机才能完成我正在做的任何其他事情 import pygame pygame init WIDTH 1366 HEIGHT
  • 获取由 css column-width 创建的列数[重复]

    这个问题在这里已经有答案了 可能的重复 如何在 Javascript 中获取 css3 多列计数 https stackoverflow com questions 6989306 how to get css3 multi column
  • 为什么ArrayList类的removeRange方法不起作用? [复制]

    这个问题在这里已经有答案了 我正在尝试使用removeRange从中删除某些元素的方法ArrayList 我从这里开始了解这个方法 http docs oracle com javase 7 docs api java util Array
  • 如何组织嵌入式项目中的代码?

    高度嵌入式 有限的代码和 RAM 大小 项目给代码组织带来了独特的挑战 我见过很多完全没有组织的项目 主要是由硬件工程师完成的 根据我的经验 他们通常不关心代码的非功能方面 但是 我一直在尝试相应地组织我的代码 硬件特定 驱动程序 初始化
  • 文本浮动在图像旁边的块中

    我想实现以下定位 两个不同的文本 块中 浮动 内嵌在图像旁边 div 内的所有内容 我一直在尝试使用不同的显示设置 块 内联文本等 但它仍然无法正常工作 HTML div class res img src gt span TITLEe s
  • 在 MATLAB 中序列化多维数组以进行数据库插入的最简单方法?

    我似乎找不到任何用于序列化数据的标准函数 我有一个大型 128x51 数组 需要将其存储在单个数据库字段中 如果没有某种序列化 事情就会出现问题 解决这个问题的最好方法是什么 我不太使用matlab 所以我不熟悉标准程序 一种可能性是使用T
  • 使用 openrowset 将 Excel 文件读入临时表;我如何引用该表?

    我正在尝试编写一个存储过程 它将 Excel 文件读入临时表 然后处理该表中的一些数据 然后将该表中选定的行插入到永久表中 所以 它是这样开始的 SET SQL select into mytemptable FROM OPENROWSET
  • 单击“模块”选项卡时,是否可以让 Doxygen 直接显示唯一的模块?

    考虑以下单文件项目 defgroup api Public API This is foo and bar together ingroup api void foobar Nothing here to see 在包含该文件的目录中 我运
  • 在循环中延迟释放资源的正确方法?

    我需要在循环中对数据库进行 SQL 查询 for rows Next fields err db Query if err nil defer fields Close do something with fields 什么会更好 保持原样