// sum 相当于函数内的局部变量,被初始化为零 funcadd(a, b int)(sum int) { sum = a + b return// return sum 的简写 // 如果是 sum := a + b 则相当于声明一个 sum 变量命名返回变量 sum 覆盖, // 最后需要显式使用 return sum }
不支持默认值参数
不支持函数重载
不支持函数嵌套,严格的讲是不支持命名函数的嵌套定义,但是支持嵌套匿名函数
1 2 3 4 5 6
funcadd(a, b int)(sum int) { anonymous := func(x, y int)int { return x + y } return anonymous(a, b) }
多值返回
定义多值返回的返回参数列表需要使用()包裹
1 2 3
funcswap(a, b int)(int, int){ return b, a }
习惯用法:
如果多值返回值有错误类型,则一般将错误类型作为最后一个返回值。
不定参数
所有不定参数类型必须是相同的
不定参数必须是函数的最后一个参数
不定参数在函数体内相当于切片,对切片的操作同样适合对不定参数的操作
切片可以作为参数传递给不定参数,切片名后要加上 “…”
1 2 3 4 5 6 7 8 9 10 11 12 13
funcsum(arr ...int)(sum int) { for _, v := range arr { sum += v } return } funcmain(){ slice := []int{1, 2, 3, 4} array := [...]int{1, 2, 3, 4} // 数组不可以作为实参传递给不定参数的函数 sum(slice...) // sum(array...) 不允许 }
形参为不定参数的函数和形参为切片的函数类型不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funcsum1(arr ...int)(sum int) { for v := range arr { sum += v } return }
funcsum2(arr []int)(sum int) { for v := range arr { sum += v } return } funcmain() { fmt.Printf("%T\n", sum1) fmt.Printf("%T\n", sum2) }
函数签名
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcadd(a, b int)int { return a + b }
type Op func(int, int)int // 定义一个函数类型 funcdo(f Op, a, b int)int { //定义一个函数,第一个参数是函数类型Op return f(a, b) // 函数类型变量可以直接用来进行函数调用 } // 函数类型、map、slice、chan 一样,时间函数类型变量和函数名都可以当作指针变量,该指针指向函数代码的初始位置。 funcmain() { a := do(add, 1, 2) //函数名 add 可以当做相同函数类型形参,不需要强制类型转换 fmt.Println(a) }
函数赋值
1 2 3 4 5 6 7 8
funcsum(a, b int)int { return a + b } funcmain() { sum(3, 4) f := sum f(1, 2) }
funcdoinput(f func (int, int)int, a, bint) int { return f(a, b) }
// 匿名函数做为返回值 funcwrap(op string)func(int, int)int { switch op { case"add": returnfunc(a, b int)int { return a + b } case"sub": returnfunc(a, b int)int { return a - b } default: returnnil } }
funcmain() { //匿名函数直接被调用 deferfunc() { if err := recover(); err != nil { fmt.Println(err) } }() sum(1, 2) // 匿名函数作为实参 doinput (func(x, y int)int { return x + y }, 1, 2) opFunc := wrap("add") re := opFunc(2, 3) fmt.Printf("%d\n", re) }
defer
Defer 关键字可以注册做个延迟调用,这些调用以先进后出(FILO)的顺序在函数返回前被执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcmain() { deferfunc(){ println("first") }() deferfunc() { println("second") }() println("function body") } // 输出结果 // function body // second // first
package main funcfa(base int)(func (int)int,func(int)int){ println(&base, base) add := func(i int)int { base += i println(&base, base) return base } sub := func(i int)int { base -= i println(&base,base) return base } return add, sub }
funcmain() { // f、g 闭包引用的 base 是同一个,是 fa 函数调用传递过来的实参值 f, g := fa(0) // s、k 闭包引用的 base 是同一个,是 fa 函数调用传递过来的实参值 s, k := fa(0) // f、g 和 s、k 引用不同的闭包变量,这是由于 fa 每次调用都要重新分配形参 println(f(1), g(2)) println(s(1), k(2)) } /* 0xc00006e000 0 0xc00006e008 0 0xc00006e000 1 0xc00006e000 -1 1 -1 0xc00006e008 1 0xc00006e008 -1 1 -1 */