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

Comments

Projects
None yet
4 participants
@beikege
Copy link

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

This comment has been minimized.

Copy link
Member

commented Oct 11, 2015

Nope. Line 370.

@bradfitz bradfitz closed this Oct 11, 2015

@beikege

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Author

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.
You can’t perform that action at this time.