天天看点

Golang入门专题-Function

作者:中国行思者

Function

函数定义的方式:func plus(a int, b int) int {}

package main

import "fmt"

func plus(a int, b int) int {

    return a + b
}
// 相同类型的入参可以这样定义
func plusPlus(a, b, c int) int {
    return a + b + c
}

func main() {

    res := plus(1, 2)
    fmt.Println("1+2 =", res)

    res = plusPlus(1, 2, 3)
    fmt.Println("1+2+3 =", res)
}           

多返回值

多返回值是Go的一大特色之一,非常有用。

package main

import "fmt"

func vals() (int, int) {
    return 3, 7
}

func main() {

    a, b := vals()
    fmt.Println(a)
    fmt.Println(b)

    _, c := vals()
    fmt.Println(c)
}           

可变参数函数

这里的可变是指入参长度可变。可变参数函数的入参类型为:...类型:

package main

import "fmt"

// 传入之后,nums的实际类型就是[]int
func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0

    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}

func main() {
    // 调用时只需要按常规方式调用
    sum(1, 2)
    sum(1, 2, 3)
  
    // 也可以将已经是slice的结构传入,但要在其后面加...(真神奇)
    nums := []int{1, 2, 3, 4}
    sum(nums...)
}           

上面的程序输出:

$ go run variadic-functions.go 
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10           

Closure闭包

这个翻译实在拗口。Go 支持可以形成闭包的匿名函数。当你想内联定义一个函数而不必命名时,匿名函数很有用。有些朋友已经想到了,没错,跟lambda有点像。闭包本质上是一个结构体,包含了函数入口和函数内定义的变量。

package main

import "fmt"

func intSeq() func() int {
    i := 0
    return func() int {
        i++
        return i
    }
}

func main() {

    nextInt := intSeq()

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())

    newInts := intSeq()
    fmt.Println(newInts())
}           

上面的程序输出:

$ go run closures.go
1
2
3
1           

闭包,到底包住了什么呢?比如上面的例子,包住了一个“函数变量i”,每个intSeq函数都捕捉着自己的i,在每次调用函数时,i都实现有状态变化。神奇,这搞出了类成员变量的感觉。

递归

递归两要素:1. 自己调自己;2. 有终止条件。

package main

import "fmt"

func fact(n int) int {
    // 递归终止条件
    if n == 0 {
        return 1
    }
    return n * fact(n-1)
}

func main() {
    fmt.Println(fact(7))

    var fib func(n int) int
    // 闭包也可以是递归的,但这需要var在定义闭包之前用类型显式声明闭包
    fib = func(n int) int {
        if n < 2 {
            return n
        }

        return fib(n-1) + fib(n-2)
    }
    // 在main内部来说,fib就是一个闭包
    fmt.Println(fib(7))
}           

上面的程序输出:

$ go run recursion.go 
5040
13           

每日一Tip

Go的函数非常灵活,结合闭包的使用,可以实现类似Java的lambda效果。

继续阅读