天天看點

Go語言學習筆記--函數

函數編寫的順序無關緊要,鑒于可讀性,最好把main()函數寫在檔案的前面

Go裡面有三中類型的函數:

普通的帶有名字的函數

匿名函數或者lambda函數

方法(Methods)

注意:

**go語言不允許函數重載,沒有泛型概念

**函數簽名:函數參數,傳回值以及它們的類型被統稱為函數簽名

**空白符“_”

傳回值:

函數可以傳回多個值,相當于python的元組。

  1. 如果一個函數需要傳回四五個值,我們可以傳遞一個切片給函數(如果傳回值具有相同類型),或者傳遞一個結構體(如果傳回值具有不同類型)。因為傳遞一個指針允許直接修改原來的值,消耗更少。
  2. 命名傳回值和非命名傳回值
    1. func getX2AndX3(input int) (int, int)
    2. func getX2AndX3_2(input int) (x2 int, x3 int)
  1. 函數參數:
    1. 按值傳遞參數:傳遞的是參數的副本,接受參數副本之後,修改值,不會影響原來的變量。
    2. 按引用傳遞參數:将參數的位址傳遞給函數,可以修改參數原來的值。函數調用時,像切片,字典,接口,通道這樣的引用類型都是預設使用引用傳遞,及時沒有顯示的指出指針
  2. 傳遞變長參數:
    1. 如果函數的最後一個參數是采用…type的形式,那麼為變長參數
func Greeting(prefix string, who ...string)

Greeting("hello:", "Joe", "Anna", "Eileen")
           

                              變量who 的值為 []string{"Joe", "Anna", "Eileen"}

  1. 如果可變長參數類型一樣,可以使用slice或者數組左參數
  1. 如果可變長參數的類型不一樣,可以使用結構和空接口做參數
    1. 結構:參數個數和類型已知,但不行同
    2. 空接口:參數個數和類型未知,一般會使用for-range循環以及switch對結構中每個參數類型進行判斷
func typecheck(..,..,values … interface{}) {

    for _, value := range values {

        switch v := value.(type) {

            case int: …

            case float: …

            case string: …

            case bool: …

            default: …

        }

    }

}
           
  1. defer和追蹤
    1. 關鍵字defer允許我們推遲到函數傳回之前,或者任意位置執行return語句之後一刻才執行猴哥語句或函數。類似其他語言的finally,一般用于釋放某些已配置設定的資源。
    2. 使用defer語句實作代碼追蹤
    3. 使用defer語句來記錄函數的參數與傳回值

當有多個defer行為被注冊時,它們會逆序執行(類型棧,即後進先出)

  1. 内置函數
    1. Go語言擁有一些不需要進行導入操作就可以使用的内置函數。
  2. 遞歸函數
    1. 函數調用函數自身
  3. 将函數作為參數
    1. 函數可以作為其他函數的參數進行傳遞,然後在其它函數内調用執行,一般稱之為回調
  1. 匿名函數(閉包):
    1. 匿名函數不能夠獨立存在,但是可以指派給變量,這樣變量就儲存了該函數的位址,然後通過變量名對函數進行調用

fplus := func(x, y int) int { return x + y };fplus(3,4)

  1. defer配合匿名函數使用
  1. 應用閉包:将函數作為傳回值
    1. 閉包函數儲存并積累其中的變量的值,不管外部函數推出與否,它都能夠繼續操作外部函數中的局部變量。

func Add2() (func(b int) int)

func Adder(a int) (func(b int) int)

  1. 使用閉包調試調試
  2. 計算函數執行時間:
    1. 使用time包中的Now()和Sub函數
    2. start := time.Now(); …;end = time.Now();dellta := end.Sub(start)