函数
- 基本语法
1 | func 函数名 (形参列表) (返回值列表) { |
函数要点
- Go函数支持返回多个值
- 如果返回多个值时,在接收时,希望忽略某个返回值,则使用
_
符号表示占位忽略 - 如果返回值只有一个,可以不写()
- Go函数不支持重载
- Go中函数也是一种数据类型,可以赋值给变量,则该变量就是函数类型的变量,通过该变量可以对函数调用
- Go支持对函数返回值命名,这样好处是返回值顺序不怕错乱
- Go支持可变参数,可变参数一定要放在形参列表最后
- 函数参数类型省略的形参,会以最靠后一个有定义类型的形参类型统一
1 | package main |
init函数
每个源文件都可以包含一个init函数
init函数要点
- init函数会在main函数之前被执行
- 如果源文件由全局变量,则顺序是全局变量先定义,然后到init在到main函数
1 | package main |
匿名函数
如果我们某个函数只希望使用一次,可以考虑使用匿名函数,当然,匿名函数也可以被多次调用
1 | package main |
闭包
闭包就是一个函数和与其相关的引用环境组合成一个整体
可以理解为,闭包是类
1 | package main |
defer
为了在函数执行完毕后,及时的释放资源,Go提供了defer(延时机制)
defer要点
- 当执行到defer时,defer修饰的语句先不执行,会被压入独立的栈中
- 当函数执行完毕后,在从defer栈,按照先入后出的方式出栈,执行
- 在defer将放入栈时,也会将相关的值拷贝同时入栈
函数参数的传递方式
参数传递方式
- 值传递
- 引用传递
不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低
函数类型定义
为了简化数据类型定义,Go支持自定义数据类型
package main
import (
"fmt"
)
func func2(i int, j int) int {
fmt.Println("func1.....", i, j)
return i
}
// 全局定义函数类型
type myFunc2 func(int, int) int
func main() {
// 局部内定义一个int类型
type int2 int
var num1 int2 = 30
var num2 int = int(num1)
fmt.Println(num1, num2)
var fun2 = func2
var fun3 myFunc2 = func2
fun2(1, 2)
fun3(1, 3)
}