golang defer粗解

php轉golang中,對defer關鍵字寫一下初步的心得php

defer特性:golang

  • defer是本身最早入棧,而後將其位置以後的函數壓入棧,等return或者panic之後,按照先進後出的原則本身最後執行,達到目的

  • defer的函數的參數在執行defer函數時計算,defer函數的變量的值在執行時計算.執行的時候是多少,就將對應值帶入

代碼放上來(defer的三個不一樣位置以及不一樣的函數返回的值也不一樣)數據庫

package main

import "fmt"

func main() {
	println(DeferFunc1(1))
	println(DeferFunc2(1))
	println(DeferFunc3(1))
}

func DeferFunc1(i int) (t int) {
	t = i  
	fmt.Println("t1",t);
	defer func() {
		fmt.Println("t3",t);
		t += 3
		fmt.Println("t4",t);
	}()
	fmt.Println("t2",t);
	return
}

func DeferFunc2(i int) int {
	t := i
	fmt.Println("t5",t);
	defer func() {
		fmt.Println("t7",t);
		t += 3
		fmt.Println("t8",t);
	}()
	fmt.Println("t6",t);
	return t
}

func DeferFunc3(i int) (t int) {
	fmt.Println("t9",t);
	defer func() {
		fmt.Println("t11",t);
		t += i
		fmt.Println("t12",t);
	}()
	fmt.Println("t10",t);
	return 2
}
複製代碼

先放出來結果bash

由於結果很長,一次性輸出三個函數的值,因此橫向擺放,看起來能簡單一些

函數輸出結果

第一個函數

1.該函數初始化時定義了返回參數的名字t 而且定義了返回的類型 t的初始值是0 且t的做用域爲整個函數(劃重點)
2.該函數執行時 t被賦值爲1 因此t1打印出來爲1
3.return的時候t的值依舊是1 且return後執行了defer t3位置接受到的t值爲1 也是毫無疑問的
4.t3位置後,t+3=4,由於!由於t的做用域是整個函數,因此t=4之後t的值被保留,故第一個函數返回的值是4

第二個函數

1.該函數只定義的返回的值,只要是該類型的變量就能夠
2.t初始化爲i,因爲t是在函數內部定義,因此t的做用域是該函數內
3.return的時候t的值依舊是1
4.t7的時候接收到了t的值爲1,t以後+3=4,t8接收也是4,可是在返回的時候因爲t的做用域只是該函數內,因此返回的t的值並無被defer內的操做替換,依舊是1

第三個函數

認真看了前兩個的解析的同窗應該第三個很好理解了
1.是定義了個做用域整個函數的返回值t
2.返回t的值爲2
3.defer接收到返回值t爲2 並加了i的值爲3
4.因爲t的做用域爲整個函數,因此返回t的值爲3

總結:若是defer要返回某些參數的值,而不是普通的關閉數據庫鏈接等等,那麼要選擇好對應參數的做用域,做用域不一樣結果也是截然不同函數

(over. 若有不一樣意見歡迎文明交流,但願各位大佬給出指點意見)ui

相關文章
相關標籤/搜索