搜尋
首頁後端開發Golanggo語言中函數與方法介紹

go語言中函數與方法介紹

Jan 06, 2020 pm 05:51 PM
go語言函數

go語言中函數與方法介紹

如果你遇到沒有函數體的函數聲明,表示該函數不是以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中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除
使用GO編程語言構建可擴展系統使用GO編程語言構建可擴展系統Apr 25, 2025 am 12:19 AM

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

有效地使用Init功能的最佳實踐有效地使用Init功能的最佳實踐Apr 25, 2025 am 12:18 AM

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

INIT函數在GO軟件包中的執行順序INIT函數在GO軟件包中的執行順序Apr 25, 2025 am 12:14 AM

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

在GO中定義和使用自定義接口在GO中定義和使用自定義接口Apr 25, 2025 am 12:09 AM

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

在GO中使用接口進行模擬和測試在GO中使用接口進行模擬和測試Apr 25, 2025 am 12:07 AM

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

在GO中使用init進行包裝初始化在GO中使用init進行包裝初始化Apr 24, 2025 pm 06:25 PM

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

GO的選擇語句:多路復用並發操作GO的選擇語句:多路復用並發操作Apr 24, 2025 pm 05:21 PM

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

GO中的高級並發技術:上下文和候補組GO中的高級並發技術:上下文和候補組Apr 24, 2025 pm 05:09 PM

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

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

MantisBT

MantisBT

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器