日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go 函数,包(二)

發布時間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go 函数,包(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#### Go 函數,包(二)
***百丈峰,松如浪,地勢坤,厚德載物之像***
今天又到周五啦,你們有沒有激動呢,反正我很激動,又有兩天的自由了;
上一節我們學習了Go 的函數和包的一些知識 , 今天接著學習...
---
##### init 函數
每個程序源文件都可以包含一個init 函數, 該函數在main 函數前執行,被Go 運行框架調用; package mainimport "fmt"func init(){fmt.Print("init ") } func main() {fmt.Print("main") }

  


輸出結果: init main
init 函數的注意事項和細節:
1. 如果一個文件同時包含***全局變量定義,init函數和main 函數***則執行的流程為全局變量定義->init函數->main函數;
2. 其主要作用是完成一些初始化工作
3. 如果多個包都有init 函數時,執行順序為導入順序,如:
A 導入了 B , B 導入了 C , 那么執行順序為先執行C 中的全局變量定義,init 函數,再執行B 包中的, 最后執行A 包中的; package mainimport "fmt" var a = test01() func init(){fmt.Println("init") // 執行順序2 fmt.Println(a) // 執行順序3 } func test01() int {fmt.Println("test01") // 執行順序1return 1 } func main() {fmt.Println("main") // 執行順序4 }

  


---
##### 匿名函數
Go 支持匿名函數,匿名函數也就是沒有名字的函數,如果某一個函數希望使用一次,可以使用匿名函數,同時匿名函數也可以實現多次調用;
如果將匿名函數賦值給一個全局變量,那么這個匿名函數就成為了一個全局匿名函數,在程序的有效作用域都有效;

package mainimport "fmt"func main(){// 定義時直接調用sum := func(a,b int) int {return a +b}(10,20)fmt.Println(sum)// 將匿名函數賦值給一個變量,通過變量調用匿名函數a := func(a,b int) int {return a+b}sum = a(10,20)fmt.Println(sum) }

  


---
##### 閉包
閉包實際上就是一個函數和與其相關的引用環境組合的一個整體 package mainimport "fmt"func add()func(int)int{var n int = 1return func(i int) int {n += ireturn n} } func main(){a := add()fmt.Println(a(1)) // 2fmt.Println(a(10)) //12fmt.Println(a(2)) //14 }

  


說明:
1. add 是一個函數,返回的數據類型是一個匿名函數;
2. 返回的匿名函數 引用到add 函數的變量n ,因此返回的匿名函數就和n 形成一個整體,構成閉包;
3. 也可以這樣理解: 閉包是類,函數是方法,n 是字段,函數和它使用的n 構成閉包;
4. 因此當反復調用a 函數時, n 將累計; package mainimport ("fmt""strings" )func addStr() func(str string) string {var base = "a"return func(str string) string {base += strreturn base} } // 判斷字符串的后綴是否為指定的 func makeSuffix(suffix string) func(string) string {return func(s string) string {if !strings.HasSuffix(s,suffix) {return s + suffix}return s} } func main(){a := addStr()fmt.Println(a("b")) // abfmt.Println(a("c")) // abcfmt.Println(a("d")) // abcdjpg := makeSuffix(".jpg")png := makeSuffix(".png")fmt.Println(jpg("a.jpg")) // a.jpgfmt.Println(jpg("b")) //b.jpgfmt.Println(png("a.png")) // a.pngfmt.Println(png("b")) //b.png }

  


1. 返回的匿名函數和參數suffix 變量組合成一個閉包,因此傳入一次可以多次調用;
---
##### defer 函數
defer 也稱為延時執行;
當函數執行到defer 時,暫時不執行,將defer 后的語句壓入獨立的棧,當函數執行完畢,return 前,再從defer 棧按照先入后出原則方式執行; package mainimport "fmt"func add(a,b int) int {defer fmt.Println("a=",a) //10 輸出順序3 , 在將語句放入棧時,相關參數的值會進行拷貝defer fmt.Println("b=",b) //20 輸出順序2 , 在將語句放入棧時,相關參數的值會進行拷貝a = 11sum := a + bdefer fmt.Println("sum=",sum) //31 輸出順序1return sum } func main(){sum := add(10,20)fmt.Println(sum) //31 輸出順序4 }

  


***在defer 將語句入到棧時,會將相關參數的值進行拷貝***
1. 在Go 開發中通常會在創建資源(打開文件,連接數據庫,鎖資源)后使用defer file.Close() conn.Close()
2. 在defer 后,仍可以繼續使用已經創建的資源;
---
##### 函數參數傳遞方式
上一節中已經講過函數參數的值類型與引用類型,我們再來深入總結一下,這個知識點在編譯型語言中很重要;
1. 函數參數是值類型時就是值傳遞,函數參數是引用類型就是引用傳遞;
2. 不管是值傳遞還是引用傳遞,傳遞給函數的都是變量的副本,不同的是值傳遞是值的拷貝,引用傳遞是地址的拷貝;
3. 一般情況下地址拷貝效率高,而值拷貝由參數的數據大小, 數據越大,效率越低;
4. 值類型: 基本數據類型int 系列, float 系列, bool, string, 數組,結構體;
5. 引用類型: 指針,slice 切片, map , chan ,interface ; package mainimport "fmt"// 值傳遞 func test01(a int){fmt.Printf("[test01] a value= %d a address=%p\n",a,&a) } // 對于值傳遞希望更改原來的值可以傳入變量地址 func test03(a *int){*a = 100fmt.Printf("[test03] c value=%v c address=%p\n",*a,&a) } // 引用傳遞 func test02(a []int){fmt.Printf("[test02] b value=%v b address=%p\n",a,&a) } func main(){var a int = 10fmt.Printf("a value= %d a address=%p\n",a,&a)test01(a)var b = []int{1,2}fmt.Printf("b value=%v b address=%p\n",b,&b)test02(b)var c = 10test03(&c)fmt.Printf("c value=%v c address=%p\n",c,&c) }

  


---
##### 變量的作用域
1. 函數內部聲明或定義的變量是局部變量,作用域限于函數內部;
2. 函數外部聲明或定義的變量是全局變量,作用域在整個包有效,若首字母大寫,則作用域為整個程序;
3. 如果變量聲明或定義在代碼塊內,如: if/for 代碼塊內,則作用域僅限于代碼塊; package mainimport "fmt"// 全局變量 var name = "golang" // 如果首字母大寫,則在整個程序中有效,其它包也可以使用 var Age = 22func test01(){// 局部變量var a int = 10fmt.Println(a)// 使用全局變量fmt.Println(name)if a > 2 {// 代碼塊內部的局部變量, 僅限于if 代碼塊有效var d int = 100fmt.Println(d)}// 代碼塊內部的局部變量, 僅限于if 代碼塊有效//fmt.Println(d) // error } func main(){// 局部變量var b int = 1fmt.Println(b)// 使用全局變量fmt.Println(name)test01() }

  個人微信公眾號上有最新文章: 歡迎大家關注一同學習交流

轉載于:https://www.cnblogs.com/Mail-maomao/p/11411767.html

總結

以上是生活随笔為你收集整理的Go 函数,包(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。