func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
dst, err := os.Create(dstName)
if err != nil {
return
}
written, err = io.Copy(dst, src)
dst.Close() // might not be called
src.Close() // might not be called
return
}
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close() // better
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close() // better
return io.Copy(dst, src)
}mu.Lock()
defer mu.Unlock()
printHeader()
defer printFooter()
func a() {
i := 0
defer fmt.Println(i)
i++
return
}
// print 0Weird 2. Deferred function calls are executed in Last In First Out order after the surrounding function returns.
func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}
// prints "3210":func c() (i int) {
defer func() { i++ }()
return 1
}
// return 2Recover is a built-in function that regains control of a panicking goroutine. Recover is only useful inside deferred functions. During normal execution, a call to recover will return nil and have no other effect. If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution.
package main
import "fmt"
func main() {
f()
fmt.Println("Returned normally from f.")
}
func f() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
fmt.Println("Calling g.")
g(0)
fmt.Println("Returned normally from g.")
}
func g(i int) {
if i > 3 {
fmt.Println("Panicking!")
panic(fmt.Sprintf("%v", i))
}
defer fmt.Println("Defer in g", i)
fmt.Println("Printing in g", i)
g(i + 1)
}Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.