跳到主要内容

函数

声明函数

普通函数的声明形式

普通函数需要先声明才能调用,一个函数的声明包括参数和函数名等,编译器通过声明才能了解函数应该怎样在调用代码和函数体之间传递参数和返回参数

声明方式

说明
  • 函数名:有字母、数字、下划线组成,其中函数名的第一个字母不能为数字,在同一个包内,函数名称不能重复
  • 参数列表 :一个参数由参数变量和参数类型组成,例如 func foo(a int, b string),其中参数列表中的变量作为函数的局部变量而存在
  • 返回参数列表:可以是返回值类型列表,也可以是类似参数列表中变量名和类型名的组合,函数在声明有返回值时,必须在函数体中使用 return 语句提供返回值列表
  • 函数体 :能够被重复调用的代码片段
func 函数名(参数列表) (返回参数列表) {
函数体
}

参数类型的简写

说明

在参数列表中,如果有多个参数变量,则以逗号分隔,如果相邻变量是同类型,则可以将类型省略

func add(a, b int) int {
return a + b
}

函数的返回值

说明

go语言支持多返回值,多返回值能方便的获得函数执行后多个返回参数,go语言经常使用多返回值中的最后一个返回参数返回函数执行中可能发生的错误

connectToNetwork 返回两个参数,conn 表示连接对象,err 返回错误

conn, err = connectToNetwork()

同一种类型返回值

说明

如果返回值是同一种类型,则用括号将多个返回值类型括起来,用逗号分隔每个返回值的类型

使用 return 语句返回时,值列表的顺序需要与函数声明的返回值类型一致

package main

import "fmt"

func typedTwoValues() (int, int) {
return 1, 2
}

func main() {
a, b := typedTwoValues() // 调用函数并解构返回值
fmt.Println(a, b) // 输出:1 2
}

带有变量名的返回值

说明

go语言支持对返回值进行命名,这样返回值就和参数一样拥有参数变量名和类型

命名的返回值变量的默认值为类型的默认值,即数值为0,字符串为空字符串,布尔为 false 、指针为 nil

package main

import "fmt"

func namedRetValues() (a, b int) { // a和b是返回值变量名
a = 1
b = 2
return
}

func main() {
x, y := namedRetValues() // x和y是接收返回值的变量名
fmt.Println(x, y) // 输出:1 2
}
注意

同一种类型返回值和命名返回值两种形式只能二选一,混用时将会发生编译错误

调用函数

函数在定义后,可以通过调用的方式,让当前的代码跳转到被调用的函数中进行执行,调用前的函数局部变量都会被保存起来不会丢失,被调用的函数结束后,恢复到被调用函数的下一行继续执行代码,之前的局部变量也能继续访问

函数内的局部变量只能在函数体中使用,函数调用结束后,这些局部变量都会被释放并且失效

函数调用格式

说明
  • 函数名 :需要调用的函数名
  • 参数列表 :参数变量以逗号分隔,尾部无须以分号结尾
  • 返回值变量列表 :多个返回值使用逗号分隔
返回值变量列表 = 函数名(参数列表)

不包含参数的调用

package main

import "fmt"

func namedRetValues() (a, b int) {
a = 1
b = 2
return
}

func main() {
x, y := namedRetValues() // 调用函数 namedRetValues,解构返回值,没有参数
fmt.Println(x, y) // 调用 fmt.Println,输出 x 和 y
}

包含参数的调用

单个参数
package main

import "fmt"

// 定义一个带单个参数的函数
func greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}

func main() {
// 调用函数时传递一个参数
message := greet("Alice")
fmt.Println(message) // 输出:Hello, Alice!
}
多个参数
package main

import "fmt"

// 定义一个带多个参数的函数
func add(a int, b int) int {
return a + b
}

func main() {
// 调用带参数的函数
result := add(3, 5)
fmt.Println("Result:", result) // 输出:Result: 8
}

可变参数的函数调用

说明

go支持可变参数,通过 ... 表示,这种函数可以接收任意数量的参数

package main

import "fmt"

// 定义一个可变参数的函数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}

func main() {
// 调用函数,传递任意数量的参数
result := sum(1, 2, 3, 4, 5)
fmt.Println("Sum:", result) // 输出:Sum: 15
}

函数变量 - 把函数作为值保存到变量中

在go语言中,函数也是一种类型,可以和其他类型一样被保存在变量中,下面的代码定义了一个函数变量 f,并将一个函数名 fire() 赋值给函数变量 f ,这样调用函数变量 f 时,实际调用的就是 fire() 函数

package main

import "fmt"

func fire() {
fmt.Println("我尼玛,爱嫂子啊?")
}

func main() {
var f func()
f = fire
f()
}

匿名函数 - 没有函数名字的函数

说明

go语言支持匿名函数,即在需要使用函数时,再定义函数,匿名函数没有函数名,只有函数体,函数可以被作为一种类型被赋值给函数类型的变量,匿名函数也往往以变量方式被传递

匿名函数经常被用于实现回调函数、闭包等

定义匿名函数

匿名函数的定义格式

func(参数列表) (返回参数列表) {
函数体
}

匿名函数的定义就是没有名字的普通函数定义

在定义时调用匿名函数

func(data int) {
fmt.Println("hello", data)
}(100) // (100)表示对匿名函数进行调用,传递参数为100

匿名函数需要放在某个函数(如 main 或自定义函数)中才能运行

package main

import "fmt"

func main() {
func(data int) {
fmt.Println("hello", data)
}(100)
}

将匿名函数赋值给变量

匿名函数体可以被赋值

package main

import "fmt"

func main() {
// 将匿名函数赋值给变量 f
f := func(data int) {
fmt.Println("hello", data)
}

// 使用 f 调用匿名函数
f(100) // 输出: hello 100
}

匿名函数用作回调函数

说明

visit 是一个接受两个参数的函数:

  • list []int: 一个 int 类型的切片(列表)
  • f func(int): 一个接受单个 int 参数的函数类型

函数逻辑:

  • 遍历 list 中的每一个元素 v
  • 调用传入的函数 f,将当前元素 v 作为参数传递给 f

调用 visit,传入两个参数:

  • 一个整数切片 []int{1, 2, 3, 4, 5}
  • 一个匿名函数 func(v int) { fmt.Println(v) },它接受一个整数 v 并打印它的值。

匿名函数在 visit 的遍历过程中被调用,每次处理一个元素

工作原理

visit 函数如何工作

  1. list []int 是切片,表示一组整数(如数组)
  2. f func(int) 是一个函数类型的参数,它接受一个 int 参数并执行用户定义的逻辑
  3. for _, v := range list 是 Go 的循环结构,按顺序迭代 list 中的每个元素,并将其值赋给变量 v
  4. f(v) 调用传入的函数 f,将当前元素 v 作为参数

main 函数的作用

  1. 定义了一个匿名函数 func(v int),它简单地打印出接收到的值
  2. 将匿名函数作为参数传递给 visit,在遍历时执行打印逻辑
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, 5}, func(v int) {
fmt.Println(v)
})
}

输出

1
2
3
4
5
Right Bottom Gif
Right Top GIF