defer`

1.2 延迟函数

• 如果有很多调用defer，那么defer是采用后进先出模式

• 在离开所在的方法时，执行（报错的时候也会执行）

``````func ReadWrite() bool {
file.Open("file")
defer file.Close()
if failureX {
return false
} i
f failureY {
return false
}
return true
}
``````

``````package main

import "fmt"

func main() {
a := 1
b := 2
defer fmt.Println(b)
fmt.Println(a)
}
``````

``````1
2
``````

``````package main

import (
"fmt"
)

func finished() {
fmt.Println("Finished finding largest")
}

func largest(nums []int) {
defer finished()
fmt.Println("Started finding largest")
max := nums[0]
for _, v := range nums {
if v > max {
max = v
}
}
fmt.Println("Largest number in", nums, "is", max)
}

func main() {
nums := []int{78, 109, 2, 563, 300}
largest(nums)
}
``````

``````Started finding largest
Largest number in [78 109 2 563 300] is 563
Finished finding largest
``````

1.3 延迟方法

``````package main

import (
"fmt"
)

type person struct {
firstName string
lastName string
}

func (p person) fullName() {
fmt.Printf("%s %s",p.firstName,p.lastName)
}

func main() {
p := person {
firstName: "John",
lastName: "Smith",
}
defer p.fullName()
fmt.Printf("Welcome ")
}
``````

``````Welcome John Smith
``````

1.4 延迟参数

``````package main

import (
"fmt"
)

func printA(a int) {
fmt.Println("value of a in deferred function", a)
}
func main() {
a := 5
defer printA(a)
a = 10
fmt.Println("value of a before deferred function call", a)
}
``````

``````value of a before deferred function call 10
value of a in deferred function 5
``````

1.5 堆栈的推迟

``````package main

import (
"fmt"
)

func main() {
name := "Naveen"
fmt.Printf("Orignal String: %s\n", string(name))
fmt.Printf("Reversed String: ")
for _, v := range []rune(name) {
defer fmt.Printf("%c", v)
}
}
``````

``````Orignal String: Naveen
Reversed String: neevaN
``````

1.6 延迟的应用

``````package main

import (
"fmt"
"sync"
)

type rect struct {
length int
width  int
}

func (r rect) area(wg *sync.WaitGroup) {
if r.length < 0 {
fmt.Printf("rect %v's length should be greater than zero\n", r)
wg.Done()
return
}
if r.width < 0 {
fmt.Printf("rect %v's width should be greater than zero\n", r)
wg.Done()
return
}
area := r.length * r.width
fmt.Printf("rect %v's area %d\n", r, area)
wg.Done()
}
func main() {
var wg sync.WaitGroup
r1 := rect{-67, 89}
r2 := rect{5, -67}
r3 := rect{8, 9}
rects := []rect{r1, r2, r3}
for _, v := range rects {
go v.area(&wg)
}
wg.Wait()
fmt.Println("All go routines finished executing")
}
``````

``````package main

import (
"fmt"
"sync"
)

type rect struct {
length int
width  int
}

func (r rect) area(wg *sync.WaitGroup) {
defer wg.Done()
if r.length < 0 {
fmt.Printf("rect %v's length should be greater than zero\n", r)
return
}
if r.width < 0 {
fmt.Printf("rect %v's width should be greater than zero\n", r)
return
}
area := r.length * r.width
fmt.Printf("rect %v's area %d\n", r, area)
}
func main() {
var wg sync.WaitGroup
r1 := rect{-67, 89}
r2 := rect{5, -67}
r3 := rect{8, 9}
rects := []rect{r1, r2, r3}
for _, v := range rects {
go v.area(&wg)
}
wg.Wait()
fmt.Println("All go routines finished executing")
}
``````

``````rect {8 9}'s area 72
rect {-67 89}'s length should be greater than zero
rect {5 -67}'s width should be greater than zero
All go routines finished executing
``````