C語言中文網 目錄
首頁 > Go語言教程 > Go語言函數 閱讀:3,662

Go語言匿名函數——沒有函數名字的函數

Go 語言支持匿名函數,即在需要使用函數時,再定義函數,匿名函數沒有函數名,只有函數體,函數可以被作為一種類型被賦值給函數類型的變量,匿名函數也往往以變量方式被傳遞。

匿名函數經常被用于實現回調函數、閉包等。

定義一個匿名函數

匿名函數的定義格式如下:

func(參數列表)(返回參數列表){
    函數體
}

匿名函數的定義就是沒有名字的普通函數定義。

1) 在定義時調用匿名函數

匿名函數可以在聲明后調用,例如:
func(data int) {
    fmt.Println("hello", data)
}(100)
注意第3行“}”后的(100),表示對匿名函數進行調用,傳遞參數為 100。

2) 將匿名函數賦值給變量

匿名函數體可以被賦值,例如:
// 將匿名函數體保存到f()中
f := func(data int) {
    fmt.Println("hello", data)
}

// 使用f()調用
f(100)
匿名函數的用途非常廣泛,匿名函數本身是一種值,可以方便地保存在各種容器中實現回調函數和操作封裝。

匿名函數用作回調函數

下面的代碼實現對切片的遍歷操作,遍歷中訪問每個元素的操作使用匿名函數來實現。用戶傳入不同的匿名函數體可以實現對元素不同的遍歷操作,代碼如下:
package main

import (
    "fmt"
)

// 遍歷切片的每個元素, 通過給定函數進行元素訪問
func visit(list []int, f func(int)) {

    for _, v := range list {
        f(v)
    }
}

func main() {

    // 使用匿名函數打印切片內容
    visit([]int{1, 2, 3, 4}, func(v int) {
        fmt.Println(v)
    })
}
代碼說明如下:
  • 第 8 行,使用 visit() 函數將整個遍歷過程進行封裝,當要獲取遍歷期間的切片值時,只需要給 visit() 傳入一個回調參數即可。
  • 第 18 行,準備一個整型切片 []int{1,2,3,4} 傳入 visit() 函數作為遍歷的數據。
  • 第 19~20 行,定義了一個匿名函數,作用是將遍歷的每個值打印出來。

匿名函數作為回調函數的設計在 Go 語言的系統包中也比較常見,strings 包中就有如下代碼:
func TrimFunc(s string, f func(rune) bool) string {
    return TrimRightFunc(TrimLeftFunc(s, f), f)
}

使用匿名函數實現操作封裝

下面這段代碼將匿名函數作為 map 的鍵值,通過命令行參數動態調用匿名函數,代碼如下:
package main

import (
    "flag"
    "fmt"
)

var skillParam = flag.String("skill", "", "skill to perform")

func main() {

    flag.Parse()

    var skill = map[string]func(){
        "fire": func() {
            fmt.Println("chicken fire")
        },
        "run": func() {
            fmt.Println("soldier run")
        },
        "fly": func() {
            fmt.Println("angel fly")
        },
    }

    if f, ok := skill[*skillParam]; ok {
        f()
    } else {
        fmt.Println("skill not found")
    }

}
代碼說明如下:
  • 第 8 行,定義命令行參數 skill,從命令行輸入— skill 可以將空格后的字符串傳入 skillParam 指針變量。
  • 第 12 行,解析命令行參數,解析完成后,skillParam 指針變量將指向命令行傳入的值。
  • 第 14 行,定義一個從字符串映射到 func()的map,然后填充這個 map。
  • 第 15~23 行,初始化 map 的鍵值對,值為匿名函數。
  • 第 26 行,skillParam 是一個 *string 類型的指針變量,使用 *skillParam 獲取到命令行傳過來的值,并在 map 中查找對應命令行參數指定的字符串的函數。
  • 第 29 行,如果在 map 定義中存在這個參數就調用;否則打印“技能沒有找到”。

運行代碼,結果如下:
$  go run main.go --skill=fly
angel fly
$  go run main.go --skill=run
soldier run

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo