在go語言中,函數(shù)是組織好的、可重復(fù)使用的、用來實現(xiàn)單一具體或相關(guān)聯(lián)功能的代碼段(塊);其主要目的是提高應(yīng)用的模塊性和代碼的重復(fù)利用率,更好的管理代碼,模塊化開發(fā)。函數(shù)通常使用參數(shù)和返回值,與調(diào)用者交互數(shù)據(jù);參數(shù)給函數(shù)傳遞數(shù)據(jù),返回值,函數(shù)將處理好的數(shù)據(jù)傳遞給調(diào)用者。
php入門到就業(yè)線上直播課:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用
本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。
函數(shù)是組織好的、可重復(fù)使用的、用來實現(xiàn)單一或相關(guān)聯(lián)功能的代碼段,其可以提高應(yīng)用的模塊性和代碼的重復(fù)利用率。
函數(shù)概述
函數(shù),function,獨立的,用于實現(xiàn)具體功能的代碼塊。主要目的,是代碼的重用(重復(fù)使用),更好的管理代碼,模塊化開發(fā)。 函數(shù)通常使用參數(shù)和返回值,與調(diào)用者交互數(shù)據(jù)。參數(shù)給函數(shù)傳遞數(shù)據(jù),返回值,函數(shù)將處理好的數(shù)據(jù)傳遞給調(diào)用者。 Go語言中函數(shù)被稱為一等公民(first-class)。意味著支持高階函數(shù),支持匿名函數(shù),支持閉包等特性,可以滿足接口等高級函數(shù)特性。
函數(shù)定義
函數(shù)構(gòu)成了代碼執(zhí)行的邏輯結(jié)構(gòu),在Go語言中,函數(shù)的基本組成為:關(guān)鍵字 func、函數(shù)名、參數(shù)列表、返回值、函數(shù)體和返回語句,每一個程序都包含很多的函數(shù),函數(shù)是基本的代碼塊。
語法:
-
定義:
func 函數(shù)名(形參列表)(返回值類型列表) { 函數(shù)體,通常會有return語句,返回值 }
-
調(diào)用:
函數(shù)名(實參列表)
函數(shù)名:函數(shù)的標識符,用于找到函數(shù),內(nèi)部是一個指向函數(shù)代碼的地址。 形參列表:由變量和類型構(gòu)成 返回值類型列表:函數(shù)返回值的類型,多個返回值需要指定多個。 函數(shù)體:實現(xiàn)函數(shù)功能的具體語句。 return語句:返回值語句
以上定的為命名函數(shù),不能定義在其他函數(shù)內(nèi)部。
函數(shù)參數(shù)
用于在調(diào)用函數(shù)時向函數(shù)傳遞數(shù)據(jù)。 實參,實際參數(shù)。調(diào)用時給的參數(shù)。指的是具有的特定實際數(shù)據(jù)的參數(shù)。 形參,形式參數(shù)。定義時使用的參數(shù)。指的是用來表示函數(shù)需要參數(shù),而定義時參數(shù)是沒有任實際何數(shù)據(jù)的。 當調(diào)用時會發(fā)生使用實參為形參變量賦值的過程,稱為參數(shù)的傳遞。在函數(shù)的執(zhí)行期間,形參是有具體數(shù)據(jù)的,形參當于函數(shù)內(nèi)聲明的變量。
參數(shù)的傳遞,分為值傳遞,地址傳遞兩種方式。地址傳遞時,需要形參定義為指針類型,調(diào)用時需要取得地址傳參。示例代碼:
func funcTest(p1 int, p2 *int) { p1++ *p2++ fmt.Println(p1, *p2) } func main() { var ( a1 = 42 a2 = 42 ) funcTest(a1, &a2) // 參數(shù)賦值過程 fmt.Println(a1, a2) }
以上會輸出
43 43 42 43
值傳遞,函數(shù)會得到實參的一份拷貝。地址傳遞,函數(shù)會得到實參地址,這樣函數(shù)內(nèi)通過地址對變量的修改,同時影響實參。
Go支持rest…不定數(shù)量參數(shù),定義時將不定數(shù)量形參放在形參列表的最后定義,使用 …Type的方式,演示:
定義: func funcTest(op string, nums ...int) { fmt.Println(nums) // [4, 1, 55, 12], slice切片型數(shù)據(jù) } 調(diào)用 funcTest("someOp", 4, 1, 55, 12)
接收到的參數(shù)為slice切片類型。
函數(shù)返回值
return語句用于生成返回值。需要在函數(shù)定義時確定返回值類型,支持多值返回。演示語法:
func funcTest() (int, string) { return 42, "Hank" }
可以在定義時,聲明返回的變量。這個做法叫命名返回,演示為:
func funcTest() (num int, title string) { num = 42 title = "Hank" return }
不用return任何數(shù)據(jù),直接return即可!
函數(shù)變量
函數(shù)可以看作一種特殊的指針類型,可以和其他類型一樣被保存在變量中。通過函數(shù)標識符和變量都可以訪問到該函數(shù),演示如下:
func funcTest() { fmt.Println("func() type") } func main() { fmt.Printf("%T, (%v)n", funcTest, funcTest) fn := funcTest fmt.Printf("%T, (%v)n", fn, fn) funcTest() fn() }
執(zhí)行結(jié)果:
func(), (0x48fe20) func(), (0x48fe20) func() type func() type
可見,函數(shù)標識符就是指向函數(shù)的指針??梢再x值給其他變量。
函數(shù)參數(shù)
函數(shù)也可以作為其他函數(shù)的參數(shù)來使用,演示如下:
func funcSuccess() { } func funcAsync(handle func()) { // 調(diào)用函數(shù)參數(shù) handle() } // 傳遞函數(shù)到其他函數(shù) funcAsync(success)
這種回調(diào)函數(shù)的使用語法,在處理異步邏輯時十分有用。
匿名函數(shù)
可以定義匿名函數(shù)??梢詫⒛涿瘮?shù)保存到變量中,作為參數(shù)傳遞,或者立即調(diào)用。如果函數(shù)時臨時使用函數(shù),則匿名函數(shù)是一個好選擇。示例語法:
賦值給變量 fn := func() { } fn() // 作為參數(shù) someFunc(func() { }) // 立即調(diào)用 func() { }()
閉包
由于匿名函數(shù)可以定義在其他函數(shù)內(nèi),同時變量的作用域為層疊的,也就是匿名函數(shù)可以會訪問其所在的外層函數(shù)內(nèi)的局部變量。當外層函數(shù)運行結(jié)束后,匿名函數(shù)會與其使用的外部函數(shù)的局部變量形成閉包。示例代碼:
var fn func() func outer() { v := 42 fn = func() { v ++ fmt.Print(v) } } outer() fn() // 43
此例中,fn 對應(yīng)的匿名函數(shù)與 outer() 的局部變量 v,就形成了閉包。
函數(shù)調(diào)用示意圖
var v = "global" func funcTest(v) { v = "funcTest" fmt.Println(v) } func main() { v := "main" funcTest(v) }
代碼編譯期間,會將函數(shù)代碼存放在內(nèi)存代碼區(qū)。 函數(shù)被調(diào)用時,在運行期間會在函數(shù)運行棧區(qū)開辟函數(shù)棧,內(nèi)部由局部變量標識符列表(就是局部變量),上層標識符列表引用等信息。直到運行結(jié)束,此空間才會被出棧,釋放。 函數(shù)內(nèi)部調(diào)用了新函數(shù),新函數(shù)的執(zhí)行空間入棧,要等到新函數(shù)執(zhí)行空間出棧,調(diào)用他的函數(shù)才會被出棧。 以上代碼的運行邏輯圖如下:
遞歸調(diào)用
函數(shù)內(nèi)部調(diào)用函數(shù)本身。稱之為遞歸調(diào)用。示例代碼:
func funcTest() { fmt.Println("run") funcTest() }
定義實現(xiàn)遞歸調(diào)用函數(shù)時,通常需要定義一個出口。用來確定何時不再進行遞歸調(diào)用了。一旦滿足條件,則調(diào)用停止。例如:
func funcTest(v) { fmt.Println(v, "run") v ++ if v <= 10 { funcTest() } }
典型的應(yīng)用有,樹狀菜單的處理,遍歷目錄,快速排序等。 遞歸調(diào)用的優(yōu)勢是編碼簡單,與描述的業(yè)務(wù)邏輯保持一致。
【