定义一个函数

  1. func foo1(a int, b int) int {
  2. return a + b
  3. }

函数形参必须写明类型。
如果有返回值,必须写明返回值类型,如果没有返回值可以不写。

多个返回值

  1. func foo2(a int, b int) (int, int) {
  2. return a + b, a * b
  3. }

返回值有名称

  1. func foo3(a int, b int) (c int, d int) {
  2. fmt.Println(c, d) // c 和 d 默认就已经被初始化好了
  3. c = a + b
  4. d = a * b
  5. return // return 时不用写明返回什么
  6. //return c, d // 当然写上也是可以的
  7. }

这种写法很常用,使用这种写法的好处是看函数定义就能大概知道返回值是什么。

参数、返回值类型简写

多个参数或返回值类型一样时,可以只写一次类型:

  1. func foo4(a, b int) (c, d int) {
  2. c = a + b
  3. d = a * b
  4. return
  5. }
  6. func foo5(a, b int, c, d string) { // a、b 是 int,c、d 是 string
  7. // some code
  8. }

可变参数

在参数类型前加省略号,代表可以传递多个参数(相当于 Python 中的*args),带省略号的参数只能有一个且只能位于参数列表最后面。

  1. func add(n int, nums ...int) (sum int) {
  2. fmt.Printf("%T\n", nums) // 结果:[]int
  3. sum += n
  4. for _, v := range nums {
  5. sum += v
  6. }
  7. return
  8. }

函数定义可以写在函数调用的后面

  1. func main() {
  2. _ = foo6()
  3. }
  4. func foo6() int {
  5. return 0
  6. }

函数是一等公民

Go 语言中函数是一等公民。可以赋值给另一个变量、作为参数传递、作为返回值等(这个特性在 Go 中的表现和 JS 中很像)。

  1. func log(fc func(int, int) int, a int, b int) {
  2. fmt.Println("函数开始执行")
  3. fc(a, b)
  4. fmt.Println("函数执行完成")
  5. }
  6. func foo7(a, b int) int {
  7. return a + b
  8. }
  9. func main() {
  10. a := 1
  11. b := 2
  12. log(foo7, a, b)
  13. }

匿名函数

定义匿名函数:

  1. func main() {
  2. f := func() int { return 0 } // 定义匿名函数,并将其赋值给一个变量
  3. _ = f() // 调用
  4. fmt.Printf("%T\n", f) // 结果:func() int
  5. }

:::info

  1. 如果想在一个函数内部定义函数,只能定义匿名函数,无法用常规方式定义函数。
  2. 匿名函数只能在函数内部定义,无法在全局作用域定义。 :::

匿名函数可以在定义的同时调用:

  1. func main() {
  2. func() {
  3. //some code
  4. }()
  5. }