Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: Directory do not need to be close? #12904

Closed
beikege opened this issue Oct 11, 2015 · 5 comments
Closed

net/http: Directory do not need to be close? #12904

beikege opened this issue Oct 11, 2015 · 5 comments

Comments

@beikege
Copy link

beikege commented Oct 11, 2015

https://github.com/golang/go/blob/master/src/net/http/fs.go#L400-L408

before f = ff , f don't need to be f.Close()?

@bradfitz
Copy link
Contributor

Nope. Line 370.

@beikege
Copy link
Author

beikege commented Oct 12, 2015

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Open("test")
    if err != nil {
        return
    }
    defer func() {
        fmt.Println("f.Close", f.Close())
    }()
    d, err := f.Stat()
    if err != nil {
        return
    }
    if d.IsDir() {
        ff, err := os.Open("index.html")
        if err == nil {
            defer func() {
                fmt.Println("ff.Close", ff.Close())
            }()
            f = ff
        }
    }
}

output:
ff.Close nil
f.Close invalid argument

@beikege
Copy link
Author

beikege commented Oct 12, 2015

@bradfitz

package main

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Open("test")
    if err != nil {
        return
    }
    defer func() {
        fmt.Println("f.Close", f.Close())
    }()
    d, err := f.Stat()
    if err != nil {
        return
    }
    if d.IsDir() {
        ff, err := os.Open("index.html")
        if err == nil {
            fmt.Println("f.Close", f.Close())
            f = ff
        }
    }
}

after f = ff defer f.Close() in fact, ff object
output:
f.Close nil
f.Close nil

@adg
Copy link
Contributor

adg commented Oct 12, 2015

Your example is not the same as the original code, because in this line

defer f.Close()

the name f is evaluated at the time the function is deferred (not when it is executed). So even if f is reassigned later, the Close method is still called on the original value of f.

In this line

defer func() { f.Close() }()

the value of f is evaluated at the time the deferred function is executed. Since the function captures the name f, not its value, it will call Close on whatever f is when the function returns.

@beikege
Copy link
Author

beikege commented Oct 12, 2015

Thank you.

@golang golang locked and limited conversation to collaborators Oct 12, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants