函数
func 函数名字(参数列表) (返回值列表) {}
eg:
// 没有返回值
func add() {
}
// 单个返回值
func add(a int, b int) int {
}
// 或
func add(a, b int) int {
}
// 多个返回值
func add(a int, b int) (int, int) {
}
-
-
函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
-
支持匿名函数,函数可以没有名字
-
多返回值
func add(a,b int) int {
return a + b
}
func main() {
// 将函数赋值给变量
c := add
c(10, 20) // 变量调用函数
}
type add_func func(int, int) int // 定义一个函数类型
func add(a, b int) int {
return a + b
}
// op add_func 即表示add_func的变量
func operator(op add_func, a int, b int) int {
return op(a, b)
}
func main() {
c := add
sum := operator(c, 100, 200)
fmt.Println(sum)
}
当然,也可以不用type定义,直接写
func operator(op func(int, int) int, a, b int) int {
return op(a, b)
}
// 将匿名函数赋值给变量
result := func(a1, b1 int) int {
return a1 + b1
}
result(11, 22)
// 定义时调用
result := func(a, b int) int {
return a + b
}(11, 22)
-
-
引用传递
无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于对象的大小,对象越大,则性能越低
map、slice、chan、指针、interface默认以引用方式传递
func add(a, b int) (c int) {
c = a + b
return
}
func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a + b) / 2
return
}
func add(arg...int) int { // 0个或多个参数
}
func add(a int, arg...int) int { // 1个或多个参数
}
/*
其实arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断参数的个数
*/
-
-
多个defer语句,按先进后出的方式执行
-
defer语句中的变量,在defer声明时就决定了
func a() {
i := 0
defer fmt.Println(i) // 这条语句是最后执行的,而且这里的i=0,不会受下面的i=10影响
i = 10
return
}
func f() {
for i := 0; i < 5; i++ {
defer fmt.Println("%d", i) // 根据先进后出的原则,打印4, 3, 2, 1
}
}
func read() {
file := open(filename)
defer file.Close()
// 文件操作
}
func read() {
mc.Lock()
defer mc.Unlock()
// 其他操作
}
func read() {
conn := openDatabase()
defer conn.Close()
// 其他操作
}
defer func() {
if conn != nil {
connn.Close()
}
}()

浙公网安备 33010602011771号