Go 转到延迟-在循环中打开和复制文件

Go 转到延迟-在循环中打开和复制文件,go,Go,如果我在for循环中打开一个文件,并将在迭代结束时完成,我应该立即调用Close,还是使用闭包调用trickDefer 我从chan字符串中读取了一系列文件名,其中包含要复制到zipfile中的数据。这些都是在go func中处理的 go func(fnames <-chan string, zipfilename string) { f, _ := os.Create(zipfilename) // ignore error handling for this example

如果我在
for
循环中打开一个文件,并将在迭代结束时完成,我应该立即调用
Close
,还是使用闭包调用trick
Defer

我从
chan字符串
中读取了一系列文件名,其中包含要复制到zipfile中的数据。这些都是在go func中处理的

go func(fnames <-chan string, zipfilename string) {
    f, _ := os.Create(zipfilename)  // ignore error handling for this example
    defer f.Close()
    zf := zip.NewWriter(f)
    defer zf.Close()
    for fname := range fnames {
        r, _ := os.Open(fname)
        w, _ := zf.Create(r.Name())
        io.Copy(w, r)
        w.Close()
        r.Close()
}(files, "some name.zip")

还是继续编写代码?

您应该检查错误。我知道这只是一个例子,但在这种情况下,这很重要。如果您所做的只是defer Close(),则实际上无法检查defer期间是否有错误

我写这篇文章的方法是创建一个helper函数:

func copyFileToZip(zf *zip.Writer, filename string) error {
    r, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer r.Close()

    w, err := zf.Create(r.Name())
    if err != nil {
        return err
    }
    defer w.Close()

    _, err = io.Copy(w, r)
    if err != nil {
        return err
    }

    return w.Close()
}

一旦添加了所有错误处理,函数就足够大,可以使其成为命名函数。它还有另外一个好处,即在关闭编写器时检查错误。没有必要检查读卡器的错误,因为这不会影响数据是否写入。

您应该检查错误。我知道这只是一个例子,但在这种情况下,这很重要。如果您所做的只是defer Close(),则实际上无法检查defer期间是否有错误

我写这篇文章的方法是创建一个helper函数:

func copyFileToZip(zf *zip.Writer, filename string) error {
    r, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer r.Close()

    w, err := zf.Create(r.Name())
    if err != nil {
        return err
    }
    defer w.Close()

    _, err = io.Copy(w, r)
    if err != nil {
        return err
    }

    return w.Close()
}

一旦添加了所有错误处理,函数就足够大,可以使其成为命名函数。它还有另外一个好处,即在关闭编写器时检查错误。检查读卡器的错误是不必要的,因为这不会影响数据是否被写入。

我不认为其中一个比另一个更地道,但第一个更简单。检查错误值是惯用的方法。当您添加代码时,第二种方法会更简单。我不认为一种方法比另一种方法更地道,但第一种方法更简单。检查错误值是惯用的方法。当您添加该代码时,第二种方法会更简单。
延迟w.Close()
返回w.Close()
都可以吗?这取决于类型。对于大多数类型,可以多次调用Close。我碰巧知道(通过阅读源代码)调用Close两次是有效的zip.Writer。第二次返回错误,但这是在延迟期间,因此不重要。是否可以同时执行
延迟w.Close()
返回w.Close()
?这取决于类型。对于大多数类型,可以多次调用Close。我碰巧知道(通过阅读源代码)调用Close两次是有效的zip.Writer。第二次返回错误,但这是在延迟期间,因此不重要。