defer和time
1. defer
defer
是go语言中,一个特殊的关键字,用于延迟调用
。
什么叫
延迟调用?
让函数或方法(跟在defer后的函数,我们一般称之为延迟函数)在当前函数执行完毕后但在在return
或者panic之前
执行。
比如:
func main() {
x := 10
defer func() {
x++
//这里打印11
fmt.Println("我后执行:", x)
}()
//这里打印10
fmt.Println("我先执行:", x)
return
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
defer有以下规则:
延迟函数的参数在defer语句出现时就已经确定
func main() { x := 10 defer func(x int) { //打印10 因为x传参时,值为10 fmt.Println("我后执行:", x) }(x) x++ fmt.Println("我先执行:", x) return } func deferTest() { var a = 1 //输出1 defer fmt.Println(a) a = 2 return }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17延迟函数执行按后进先出顺序执行, 即先出现的defer最后执行
func main() { x := 10 defer func(x int) { fmt.Println("我后执行1:", x) }(x) defer func(x int) { //后进先出 这个会先于我后执行1执行 fmt.Println("我后执行2:", x) }(x) x++ fmt.Println("我先执行:", x) return }
1
2
3
4
5
6
7
8
9
10
11
12
13延迟函数可以操作主函数的具名返回值
func main() { //打印2 return i 并不是一个原子操作 //return会分两步 1. 设值 2 return //所以result为先被赋值为i=1 x := deferTest() fmt.Println(x) } func deferTest() (result int) { i := 1 defer func() { result++ }() return i }
1
2
3
4
5
6
7
8
9
10
11
12
13
14如果 defer 执行的函数为 nil, 那么会在最终调用函数的产生 panic
var a func() func deferTest() *int { i := 1 defer a() return &i }
1
2
3
4
5
6
7
测试:
func main() {
x := deferTest()
fmt.Println(x)
}
func deferTest() int {
i := 1
defer func() {
i++
}()
return i
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
func main() {
x := deferTest()
fmt.Println(*x)
}
func deferTest() *int {
i := 1
defer func() {
i++
}()
return &i
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
func main() {
x := deferTest()
fmt.Println(*x)
}
func deferTest() *int {
i := 1
defer func(x *int) {
*x++
}(&i)
return &i
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
注意: defer一定要定义在
return或panic之前
,否则会不执行。
func main() {
//defer不会执行
//主动调用os.Exit不会执行defer
defer func() {
fmt.Println("defer")
}()
//退出进程
os.Exit(-1)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
2. time
在编写程序时,经常会用到时间,go语言的标准库time包提供了对时间的一系列操作。
这里我们只是简单了解一下
func main() {
//当前的时间
t := time.Now()
//格式化 这个是格式 2006-01-02 15:04:05
fmt.Println(t.Format("2006-01-02 15:04:05")) //小口决,612345
}
1
2
3
4
5
6
2
3
4
5
6
秒值,毫秒值:
func main() {
//当前的时间
t := time.Now()
//毫秒值
milli := t.UnixMilli()
//秒值
sencond := t.Unix()
fmt.Printf("毫秒值:%d, 秒值:%d \n", milli, sencond)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
时间相加相减:
func main() {
//当前的时间
t := time.Now()
fmt.Println(t.Format("2006-01-02 15:04:05"))
after20s := t.Add(20 * time.Second)
fmt.Println(after20s.Format("2006-01-02 15:04:05"))
sub := after20s.Sub(t)
fmt.Printf("相减时间:%v \n", sub)
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
休眠:
func main() {
//阻塞当前的go程x时间,x<=0时立即 释放
time.Sleep(2 * time.Second)
fmt.Println("等2秒打印出来")
}
1
2
3
4
5
2
3
4
5
经过一段时间后返回:
func main() {
ch := make(chan struct{})
go wait(ch)
select {
case <-ch:
fmt.Println("wait执行成功")
case <-time.After(2 * time.Second):
fmt.Println("wait等待时间已经超过2秒,超时了")
}
}
func wait(ch chan struct{}) {
time.Sleep(3 * time.Second)
ch <- struct{}{}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15