go--函數

函數的定義

Go語言中定義函數使用func關鍵字,具體格式以下:閉包

func 函數名(參數)(返回值){
    函數體
}

其中:函數

  • 函數名:由字母、數字、下劃線組成。但函數名的第一個字母不能是數字。在同一個包內,函數名也稱不能重名(包的概念詳見後文)。
  • 參數:參數由參數變量和參數變量的類型組成,多個參數之間使用,分隔。
  • 返回值:返回值由返回值變量和其變量類型組成,也能夠只寫返回值的類型,多個返回值必須用()包裹,並用,分隔。
  • 函數體:實現指定功能的代碼塊。
    例如:
func intSum(x int, y int) int {
    return x + y
}

// 函數的參數和返回值都是可選的
func sayHello() {
    fmt.Println("Hello World!")
}

參數

類型簡寫

函數的參數中若是相鄰變量的類型相同,則能夠省略類型,例如:code

func intSum(x, y int) int {
    return x + y
}

可變參數

可變參數是指函數的參數數量不固定。Go語言中的可變參數經過在參數名後加...來標識。回調函數

注意:可變參數一般要做爲函數的最後一個參數。string

返回值

多返回值

Go語言中函數支持多返回值,函數若是有多個返回值時必須用()將全部返回值包裹起來。class

func calc(x, y int) (int, int) {
    sum := x + y
    sub := x - y
    return sum, sub
}

返回值命名

函數定義時能夠給返回值命名,並在函數體中直接使用這些變量,最後經過return關鍵字返回。test

func calc(x, y int) (sum, sub int) {
    sum = x + y
    sub = x - y
    return
}

defer語句

Go語言中的defer語句會將其後面跟隨的語句進行延遲處理。在defer歸屬的函數即將返回時,將延遲處理的語句按defer定義的逆序進行執行,也就是說,先被defer的語句最後被執行,最後被defer的語句,最早被執行。匿名函數

func main() {
    fmt.Println("start")
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
    fmt.Println("end")
}

// 結果:start  end  3  2  1

匿名函數

匿名函數就是沒有函數名的函數,匿名函數多用於實現回調函數和閉包。變量

匿名函數的定義格式以下:引用

func(參數)(返回值){
    函數體
}

// 當即執行函數
func main() {
    func(x, y int) {
        fmt.Println(x + y)
    }(10, 20)//匿名函數定義完加()直接執行
}

閉包

閉包指的是一個函數和與其相關的引用環境組合而成的實體。簡單來講,閉包=函數+引用環境。一些閉包示例:

func adder() func(int) int {
    var x int
    return func(y int) int {
        x += y
        return x
    }
}
func main() {
    var f = adder()
    fmt.Println(f(10)) //10
    fmt.Println(f(20)) //30
    fmt.Println(f(30)) //60

    f1 := adder()
    fmt.Println(f1(40)) //40
    fmt.Println(f1(50)) //90
}

// 示例2
func adder2(x int) func(int) int {
    return func(y int) int {
        x += y
        return x
    }
}
func main() {
    var f = adder2(10)
    fmt.Println(f(10)) //20
    fmt.Println(f(20)) //40
    fmt.Println(f(30)) //70

    f1 := adder2(20)
    fmt.Println(f1(40)) //60
    fmt.Println(f1(50)) //110
}

// 示例3
func makeSuffixFunc(suffix string) func(string) string {
    return func(name string) string {
        if !strings.HasSuffix(name, suffix) {
            return name + suffix
        }
        return name
    }
}

func main() {
    jpgFunc := makeSuffixFunc(".jpg")
    txtFunc := makeSuffixFunc(".txt")
    fmt.Println(jpgFunc("test")) //test.jpg
    fmt.Println(txtFunc("test")) //test.txt
}

// 示例4
func calc(base int) (func(int) int, func(int) int) {
    add := func(i int) int {
        base += i
        return base
    }

    sub := func(i int) int {
        base -= i
        return base
    }
    return add, sub
}

func main() {
    f1, f2 := calc(10)
    fmt.Println(f1(1), f2(2)) //11 9
    fmt.Println(f1(3), f2(4)) //12 8
    fmt.Println(f1(5), f2(6)) //13 7
}
相關文章
相關標籤/搜索