Go語言系列開發之延遲呼叫和作用域
Hello,各位小夥伴大家好,我是小棧君,最近一段時間我們將繼續分享關於go語言基礎系列,當然後期小棧君已經在籌劃關於java、Python,資料分析、人工智慧和大資料等相關係列文章。希望能和大家一起學習進步,相互提高。
好了,話不多說,我們開始今天的分享,今天分享的主題是關於go語言系列中的延遲呼叫和作用域相關的知識。
延遲呼叫defer
在go語言中關鍵字 defer ⽤於延遲一個函式或者方法(或者當前所建立的匿名函式)的執行。注意,defer語句只能出現在函式或方法的內部。所以我們常用作關閉流處理或則需要進行延期處理的操作。
func main() { defer fmt.Println("小棧君在測試defer") //main結束前呼叫 fmt.Println("this is a test") /* 執行結果: this is a test 小棧君在測試defer */ }
defer語句經常被用於處理成對的操作,如開啟、關閉、連線、斷開連線、加鎖、釋放鎖。通過defer機制,不論函式邏輯多複雜,都能保證在任何執行路徑下,資源被釋放。釋放資源的defer應該直接跟在請求資源的語句後。
多個defer執行順序
如果一個函式中有多個defer語句,它們會以LIFO(後進先出)的順序執行。哪怕函式或某個延遲呼叫發生錯誤,這些呼叫依舊會被執⾏。
func test(x int) { fmt.Println(10 / x)//x為0時,產生異常 } func main() { defer fmt.Println("111") defer fmt.Println("222") defer test(0) defer fmt.Println("333") /* 執行結果: 333 222 111 panic: runtime error: integer divide by zero */ }
defer和匿名函式結合使用
小棧君這邊直接為大家舉例說明在匿名函式中使用defer 會有怎樣的效果呢?
func main() { a, b := 10, 20 defer func(x int) { // a以值傳遞方式傳給x fmt.Println("defer:", x, b) // b 閉包引用 }(a) a += 10 b += 100 fmt.Printf("a = %d, b = %d\n", a, b) /* 執行結果: a = 20, b = 120 defer: 10 120 */ }
所以在執行結果上看,使用了defer會先進行傳值,然後是最後才會計算出來
獲取命令列引數
package main
import (
"fmt"
"os"
)
func main() {
// IT小棧君
agers := os.Args
// 如果使用者輸入不正確或個數不對 則提醒
if agers != nil && len(agers) < 2 {
fmt.Println("小棧君提醒你,您輸入的位數不正確~")
return
}
fmt.Println("小棧君告訴你實際傳參==》", agers)
}
執行結果如下:
作用域
作用域為已宣告識別符號所表示的常量、型別、變數、函式或包在原始碼中的作用範圍。就好比是你在行車過程中所能夠行使的範圍一樣。
區域性變數
在函式體內宣告的變數、引數和返回值變數就是區域性變數,它們的作用域只在函式體內:
func test(a, b int) {
var c int
a, b, c = 1, 2, 3
fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
}
func main() {
//a, b, c = 1, 2, 3 //err, a, b, c不屬於此作用域
{
var i int
i = 10
fmt.Printf("i = %d\n", i)
}
//i = 20 //err, i不屬於此作用域
if a := 3; a == 3 {
fmt.Println("a = ", a)
}
//a = 4 //err,a只能if內部使用
}
全域性變數
在函式體外宣告的變數稱之為全域性變數,全域性變數可以在整個包甚至外部包(被匯出後)使用。
var a int //全域性變數的宣告
func test() {
fmt.Printf("test a = %d\n", a)
}
func main() {
a = 10
fmt.Printf("main a = %d\n", a) //main a = 10
test() //test a = 10
}
不同作用域同名變數
在不同作用域可以宣告同名的變數,其訪問原則為:在同一個作用域內,就近原則訪問最近的變數,如果此作用域沒有此變數宣告,則訪問全域性變數,如果全域性變數也沒有,則報錯。
var a int //全域性變數的宣告
func test01(a float32) {
fmt.Printf("a type = %T\n", a) //a type = float32
}
func main() {
fmt.Printf("a type = %T\n", a) //a type = int, 說明使用全域性變數的a
var a uint8 //區域性變數宣告
{
var a float64 //區域性變數宣告
fmt.Printf("a type = %T\n", a) //a type = float64
}
fmt.Printf("a type = %T\n", a) //a type = uint8
test01(3.14)
test02()
}
func test02() {
fmt.Printf("a type = %T\n", a) //a type = int
}
今天的分享就到這裡就結束啦,如果你喜歡我的分享,麻煩你點選再看,分享或留言,我是小棧君,我們下期見,拜了個拜~
本文由部落格一文多發平臺 OpenWrite 釋出!