Why not make it a named function instead of a closure? I don't think it's overkill.
There's no runtime overhead for closures that
are called in place or for function literals
that don't close over any variables. They both
behave exactly like any other named function.
Anthony
Defer is the only guarantee that you can have if something wrong
happens, so use it.
By letting the file.Close() for a later place in the code you add a
possibility that on a later change in your code the Close() call isn't
executed.
In your case, since you had a lot of open files, you should start a
goroutine with your file name and open the file there.
package main
import "sync"
func handleFile(name string, wg *sync.WaitGroup ) {
// make sure to signal when everything is done
defer wg.Done()
f, err := os.Open(name)
if err != nil {
return
}
// use f
defer f.Close()
}
func doLotsOfWork() {
done := &sync.WaitGroup{}
fileCount := 0
for _, name := range filenames {
done.Add(1)
go handleFile(name,done)
}
// block until everything is done
done.Wait()
}
>
> --
> matt kane's brain
> http://hydrogenproject.com
--
André Moraes
http://andredevchannel.blogspot.com/
oops, the right way is:
defer f.Close()
// use f
The real useful part though is:
> There's no runtime overhead for closures that
> are called in place or for function literals
> that don't close over any variables
On Mon, Apr 23, 2012 at 12:12, Ugorji Nwoke <ugo...@gmail.com> wrote:
> IMO, I think a goroutine may be heavy handed here. If the OP just wants to
> ensure a file is eventually closed, and wants it to happen within each
> iteration of the loop, then the content of each loop should be run in a
> function (externally defined or closure as he has it) and use defer as
> usual.
--
I think you can write:
for _, name := range filenames {
f, err := os.Open(name)
if err != nil { panic(err) }
defer f.Close()
// do some stuff
f.Close()
}
Rémy.
Say I have a loop that is something like this:
for _, name := range filenames {
f, err := os.Open(name)
if err != nil { panic(err) }
defer f.Close()
// do some stuff
}
http://golang.org/ref/spec#Defer_statements
Cheers
Dave
defer statements are evaluated just before the function returns to the caller.http://golang.org/ref/spec#Defer_statements
Cheers
Dave
If you need to do something at the end of a block, do it at the end of
the block. If you need to collect dangling resources on a panic, use
defer.
If you want both, use both. If you want the action to be done once,
use sync.Once.
Rémy.
it's a pity we can't close a channel twice.
From my experience its safe to call Close multiple times, I use that
pattern all the time to make sure that database connections get closed
asap (and to make sure that if I somehow miss closing them, they get
closed at the end of the function)