Golang新手两个入门问题请教

Golang新手两个入门问题请教 我注意到在代码的两个地方,我在 defer func(filename) 的末尾写了一个看起来像是标签的东西,如下所示:

	defer func(oW *os.File) {
		err := oW.Close()
		if err != nil {
			fmt.Printf("Error: %v  ......)
			os.Exit(1)
		}
	}(oW)

我的第一个问题是:末尾的 (oW) 是什么??? 这段代码是很久以前写的,我在搜索 defer func() 时找不到相关信息——这是某种可以放在代码块底部的可选信息标签吗??? 如果是,它叫什么?或者它在语法定义中的哪里,这样我才能明白自己在做什么?

第二个问题:也许这个问题更适合放在 JetBrains 论坛,因为我在使用 GoLand,但既然在这里:当我使用右上角的放大镜搜索时,没有在代码中看到搜索字符串的引用。自从上次使用后,我换了一台新电脑,我想可能是我的配置设置有问题???


更多关于Golang新手两个入门问题请教的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你正在执行闭包函数 func() {}(),因为 defer 应该是一个调用。

func() {}()

更多关于Golang新手两个入门问题请教的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


(oW) 字面上就是你传递给函数的参数。

假设这个函数不是匿名的:

func CloseFile(ow *os.File) {
		err := oW.Close()
		if err != nil {
			fmt.Printf("Error: %v  ......)
			os.Exit(1)
		}
}

你这样调用这个函数:

CloseFile(oW) // <- 这里的 (oW) 字面上
//  原因和你的例子一样。

回答第二个问题:确保选中了“全部”标签 image

关于你的第一个问题,末尾的 (oW)函数调用的一部分。在 Go 中,defer 语句后面需要跟一个函数调用。你写的是一个匿名函数的定义,但仅仅定义它并不会执行它。末尾的 (oW) 就是立即调用这个匿名函数,并将 oW 作为参数传递给它。这样,defer 延迟执行的就是这个已经被调用的匿名函数。

更清晰的解释是,你的代码可以拆解为以下步骤:

  1. 定义一个匿名函数:func(oW *os.File) { ... }
  2. 立即用参数 oW 调用它:(oW)
  3. defer 延迟执行的是这次调用的结果(即该匿名函数的执行)。

一个更简单的等效写法是:

closeFile := func(oW *os.File) {
    err := oW.Close()
    if err != nil {
        fmt.Printf("Error: %v", err)
        os.Exit(1)
    }
}
defer closeFile(oW) // 这里显式地调用了函数

你的写法只是将定义和调用合并到了一行。这在 Go 中处理 defer 时很常见,特别是当你想为延迟执行的函数传递参数时(此时参数的值会在 defer 语句执行时被确定)。

关于语法,你可以在 Go 语言规范中查看 Defer statementsFunction literals


关于你的第二个问题,这确实更可能与 GoLand 的配置或索引状态有关。不过,可以尝试以下步骤:

  1. 无效化缓存并重启:在 GoLand 中,点击菜单 File -> Invalidate Caches...,然后选择 Invalidate and Restart。这能解决很多索引问题。
  2. 检查项目根目录:确保你的项目在 GoLand 中是以正确的根目录打开的,并且 go.mod 文件位于根目录下。
  3. 重新索引:在重启后,GoLand 可能会自动开始重新索引。你也可以在 File -> Settings -> Tools -> File Watchers 中检查是否有异常,但通常无效化缓存就足够了。

如果问题依旧,建议在 JetBrains 的官方论坛或 issue tracker 提供更详细的信息(如 GoLand 版本、Go 版本、项目结构等)。

回到顶部