【问题标题】:Returning File Pointer in Golang在 Golang 中返回文件指针
【发布时间】:2016-03-20 11:35:32
【问题描述】:

我仍在努力学习 Golang 的基础知识。

考虑以下示例代码:

func OpenOutputFile(name string) (fp *os.File) {
  fp, err := os.Create(name)
  if err != nil {
      panic(err)
  }

  defer func() {
      if err := fp.Close(); err != nil {
          panic(err)
      }
  }()

  return fp
}

我会假设调用:

fp := OpenOutputFile("output.txt")

现在将 fp 设为文件指针 (*os.File),这样我就可以调用如下语句:

io.WriteString(fp, "Hello World")

在另一个函数中。但是在调用这个方法的时候,却产生了错误:

0 write output.txt: bad file descriptor

所以看来返回的指针是无效的。如何返回格式正确的指针以与io.WriteString 一起使用?

感谢您的帮助!

注意:当文件指针的创建和文件指针的写入存在于同一方法中时,一切都会按预期执行。将逻辑分解为函数会导致其行为不符合预期。

【问题讨论】:

    标签: pointers go


    【解决方案1】:

    The Go Programming Language Specification

    Defer statements

    “defer”语句调用一个函数,该函数的执行被推迟到 周围函数返回的那一刻,要么是因为 周围的函数执行了一个return语句,到达了结束 它的函数体,或者因为对应的goroutine是 惊慌失措。

    每次执行“defer”语句时,函数值和 调用的参数像往常一样被评估并重新保存,但是 实际函数没有被调用。相反,延迟函数是 在周围函数返回之前立即调用,在 相反的顺序,他们被推迟了。如果一个延迟函数值 评估为 nil,调用函数时执行恐慌,而不是 当执行“defer”语句时。

    例如,如果延迟函数是函数字面量并且 周围函数已命名范围内的结果参数 在字面量中,延迟函数可以访问和修改 返回之前的结果参数。如果延迟函数 有任何返回值,它们在函数完成时被丢弃。

    func OpenOutputFile(name string) (fp *os.File) {
        fp, err := os.Create(name)
        if err != nil {
            panic(err)
        }
    
        defer func() {
            if err := fp.Close(); err != nil {
                panic(err)
            }
        }()
    
        return fp
    }
    

    你打开文件

    fp, err := os.Create(name)
    

    你关闭文件

    err := fp.Close()
    

    Close 之后,fp 不再指向有效的文件描述符。

    【讨论】:

    • 啊,我不知道为什么我没有早点想到这一点。我以为defer() 是因为错误或其他原因而被调用的。谢谢!
    • 你不需要命名返回值。当您调用 fp, err := os.Create(name) 时,您创建的变量 fp 被您创建的变量 fp 所遮蔽
    • @user1431317:您声称fp, err := os.Create(name) 创建变量fp 是错误的。 Short variable declarations:与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初在同一个块(或参数列表,如果该块是函数体)中以相同的类型声明,并且至少有一个非空白变量是新的。重新声明不引入新变量;它只是为原始值分配一个新值。
    • 你是对的,因为它们在同一个区块中。但是你仍然不需要命名它。
    猜你喜欢
    • 1970-01-01
    • 2018-03-22
    • 2016-11-30
    • 2014-08-20
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多