如果你遇到沒有函數體的函數聲明,表示該函數不是以Go實現的。
package math func Sin(x float64) float //implemented in assembly language
如果為函數的每一個回傳值都設定變數名,則會以對應的零值初始化,且在該函數的return語句中省略操作數,這種用法稱之為 bare return。
go中的錯誤處理,習慣上是先進行一系列的初始化檢查,將處理失敗邏輯的程式碼先行處理,然後才是函數的實際邏輯,這樣使得程式碼更簡潔,避免過多的層級結構。
函數定義時,可以使用函數類型作為參數,也可以作為傳回類型,是不是有點類似委託,從而實現閉包。另外還有匿名函數,是不是類似lambda表達式。 strings.Map 函數可以拿來試驗。
func squares() func() int { var x int return func() int { x++ return x * x } } func main() { f := squares() fmt.Println(f()) // "1" fmt.Println(f()) // "4" fmt.Println(f()) // "9" fmt.Println(f()) // "16" }
匿名函數和squares中,存在變數參考。這就是函數值屬於引用類型和函數值不可比較的原因。 Go使用閉包(closures)技術實作函數值,Go程式設計師也把函數值叫做閉包。
注意golang聖經中匿名函數一節中的例子程序。
go語言的可變參函數非常好用,你可以傳遞多個同類型參數,也可以直接傳入一個該類型的切片(注意傳入切片時要使用...標記,我想應該是為了同切片參數區分吧,畢竟兩者還是有些不同的),如果想要使用不同類型的變參,那麼使用萬能的interfac{} ,函數體內像解析切片一樣解析這個變參就好了。
直到包含該defer語句的函數執行完畢時,defer後面的函數才會被執行,不論包含defer語句的函數是透過return正常結束,還是由於panic導致的例外結束。你可以在一個函數中執行多條defer語句,它們的執行順序與宣告順序相反
var mu sync.Mutex var m = make(map[string]int) func lookup(key string) int { mu.Lock() defer mu.Unlock() return m[key] }
調試複雜程式時,defer機制也常被用來記錄何時進入和退出函數。
func bigSlowOperation() { defer trace("bigSlowOperation")() // don't forget the extra parentheses // ...lots of work… time.Sleep(10 * time.Second) // simulate slow operation by sleeping } func trace(msg string) func() { start := time.Now() log.Printf("enter %s", msg) return func() { log.Printf("exit %s (%s)", msg,time.Since(start)) } }
我們只需要先命名double的回傳值,再增加defer語句,我們就可以在double每次被呼叫時,輸出參數以及回傳值。
func double(x int) (result int) { defer func() { fmt.Printf("double(%d) = %d\n", x,result) }() return x + x } _ = double(4) // Output: // "double(4) = 8"
為了方便診斷問題,runtime套件允許程式設計師輸出堆疊資訊。在下面的範例中,我們透過在main函數中延遲呼叫printStack輸出堆疊資訊。
gopl.io/ch5/defer2 func main() { defer printStack() f(3) } func printStack() { var buf [4096]byte n := runtime.Stack(buf[:], false) os.Stdout.Write(buf[:n]) }
不能為一個結構體定義同名的欄位名和方法名,有點奇怪。
函數指標:go裡其實也是有函數指標的,下面用go語言實作表格驅動模式。
package main import ( "fmt" ) func add(a int, b int) int { return a + b } func sub(a int, b int) int { return a - b } func main() { fm := make(map[int]func(int, int) int) fm[1001] = add fm[1002] = sub protocol := 2001 i := 1 j := 2 if func_handle, ok := fm[protocol]; ok { println(func_handle(i, j)) } else { fmt.Printf("protocol: %d not register!", protocol) } }
返回局部變數指針:
不同於C 語言,GO 的函數可以傳回局部變化指針,且編譯器會透過逃逸分析(escape analysis)決定是否在堆上分配記憶體。
編譯時可以透過 -gcflags "-l -m" 參數來停用函式內聯,函式內聯會對記憶體分配有一些影響,具體不清楚。
函數參數沒有所謂的引用傳遞,都是值傳遞的,差別只是傳遞的是拷貝物件還是指標。在 C 語言中,一般建議傳遞指標參數來避免複製物件提升效率。
但在go 中,被複製的指標會延長目標物件的生命週期,也可能導致它被分配到堆上,則效能消耗要加上堆記憶體分配和垃圾回收的成本,而在堆疊上複製小對像其實非常快,所以如果不是特別大的物件或確實需要修改原對象,一般不需要傳指標參數。在並發程式設計中,也提倡使用不可變物件(唯讀或複製),可以消除資料同步的麻煩。
如下就會在堆上分配內存,編譯時透過-gcflags "-m" 可查看彙編程式碼:
func test(p *int) { go func() { println(p) }() } func main() { x := 100 p := &x test(p) }
使用傳出參數,推薦使用返回值,也可以使用二等級指標:
func test(p **int) { x := 100 *p = &x } func main() { var p *int test(&p) println(*p) }
更多go語言知識請關注PHP中文網go語言教學欄位。
以上是go語言中函數與方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

goisidealforbuildingscalablesystemsduetoitssimplicity,效率和建築物內currencysupport.1)go'scleansyntaxandaxandaxandaxandMinimalisticDesignenhanceProductivityAndRedCoductivityAndRedCuceErr.2)ItSgoroutinesAndInesAndInesAndInesAndineSandChannelsEnablenableNablenableNableNablenableFifficConcurrentscorncurrentprogragrammentworking torkermenticmminging

Initfunctionsingorunautomationbeforemain()andareusefulforsettingupenvorments和InitializingVariables.usethemforsimpletasks,避免使用輔助效果,andbecautiouswithTestingTestingTestingAndLoggingTomaintAnainCodeCodeCodeClarityAndTestesto。

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

CustomInterfacesingoarecrucialforwritingFlexible,可維護,andTestableCode.TheyEnableDevelostOverostOcusonBehaviorBeiroveration,增強ModularityAndRobustness.byDefiningMethodSigntulSignatulSigntulSignTypaterSignTyperesthattypesmustemmustemmustemmustemplement,InterfaceSallowForCodeRepodEreusaperia

使用接口進行模擬和測試的原因是:接口允許定義合同而不指定實現方式,使得測試更加隔離和易於維護。 1)接口的隱式實現使創建模擬對像變得簡單,這些對像在測試中可以替代真實實現。 2)使用接口可以輕鬆地在單元測試中替換服務的真實實現,降低測試複雜性和時間。 3)接口提供的靈活性使得可以為不同測試用例更改模擬行為。 4)接口有助於從一開始就設計可測試的代碼,提高代碼的模塊化和可維護性。

在Go中,init函數用於包初始化。 1)init函數在包初始化時自動調用,適用於初始化全局變量、設置連接和加載配置文件。 2)可以有多個init函數,按文件順序執行。 3)使用時需考慮執行順序、測試難度和性能影響。 4)建議減少副作用、使用依賴注入和延遲初始化以優化init函數的使用。

go'SselectStatementTreamLinesConcurrentProgrambyMultiplexingOperations.1)itallowSwaitingOnMultipleChannEloperations,執行thefirstreadyone.2)theDefirstreadyone.2)thedefefcasepreventlocksbysbysbysbysbysbythoplocktrograpraproxrograpraprocrecrecectefnoopeready.3)

contextancandwaitgroupsarecrucialingoformanaginggoroutineseflect.1)context contextsallowsAllowsAllowsAllowsAllowsAllingCancellationAndDeadLinesAcrossapibiboundaries,確保GoroutinesCanbestoppedGrace.2)WaitGroupsSynChronizeGoroutines,確保Allimizegoroutines,確保AllizeNizeGoROutines,確保AllimizeGoroutines


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版
中文版,非常好用

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載
最受歡迎的的開源編輯器