函数参数的传递方式有值传递和引用传递(指针/slicer/map/channel/interface)两种;不管哪一种,传递的都是值或者地址的副本;一般来说,地址传递的效率更高,因为数据量小,而值传递随着数据量的增加而效率降低(如结构体拷贝)。
示例:
package main
import (
"fmt"
"reflect"
)
func getSum(num1 int, num2 int) int {
return num1+num2
}
func main() {
funcVar := getSum
fmt.Println("the type of getSum :", reflect.TypeOf(getSum),
" the type of funcVar :",reflect.TypeOf(funcVar))
res := getSum(10,20)
fmt.Println("the result : ", res)
}
运行结果:
the type of getSum : func(int, int) int
the type of funcVar : func(int, int) int
the result : 30
示例:
package main
import "fmt"
func getSum(num1 int, num2 int) int {
return num1+num2
}
func myFunc(funcVar func(int, int)int, num1 int, num2 int) int {
return funcVar(num1, num2)
}
func main() {
res := myFunc(getSum, 10,20)
fmt.Println("the result : ", res)
}
运行结果:
the result : 30
示例:
package main
import "fmt"
type myFunType func(int, int)int // //定义函数类型的类型名
func getSum(num1 int, num2 int) int {
return num1+num2
}
func myFunc(funcVar myFunType, num1 int, num2 int) int {
return funcVar(num1, num2)
}
func main() {
type myInt int //定义基本数据类型的类型名
var num myInt = 40
fmt.Println("num : ", num)
res := myFunc(getSum, 10 , 20)
fmt.Println("res : ", res)
}
运行结果:
num : 40
res : 30
示例:
package main
import "fmt"
func get_sum_sub(num1 int, num2 int) (sum int, sub int){
sum = num1 + num2
sub = num1 - num2
return
}
func main() {
sum, sub := get_sum_sub(20, 10)
fmt.Println("sum : ", sum, "sub : ", sub)
}
运行结果:
sum : 30
sub : 10
func(args... int) sum int{} // args是slice类型,可以通过args[index]访问各个值。
示例:
package main
import "fmt"
func getSum(num1 int, args... int) int{
sum := num1
for i := 0; i
运行结果:
res1= 10
res2= 100
每一个源文件都可以包含一个init函数,该函数在main函之前被go框架运行。通常可以在init函数中完成初始化工作。
Note:
package main
import "fmt"
var gVar = gTest()
func gTest() string {
fmt.Println("global variable:")
return "global variable:"
}
func init() {
fmt.Println("init function:")
}
func main() {
fmt.Println("main function:")
}
运行结果:
global variable:
init function:
main function:
Go也支持匿名函数,如果某个函数只希望使用一次,可以考虑匿名函数;当然,匿名函数也可以实现多次调用。
使用方式:
package main
import "fmt"
func main() {
// case 1:
getSum := func (num1 int, num2 int) int {
return num1 + num2
}(10,20)
fmt.Println("getSum = ", getSum)
//case 2:
getSub := func(num1 int, num2 int) int{
return num1-num2
}
res := getSub(10,20)
fmt.Println("getSub = ", res)
}
运行结果:
getSum = 30
getSub = -10
闭包就是一个函数与其相关的引用环境的一个整体(实体)
package main
import "fmt"
func addUpper() func(int)int {
var n int = 10 //外部变量
return func (x int) int { //匿名函数引用外部变量 构成闭包
n += x
return n
}
}
func main() {
myFun := addUpper()
fmt.Println("1st close function", myFun(1))
fmt.Println("2nd close function", myFun(2))
fmt.Println("3rd close function", myFun(3))
}
运行结果(每进行一次调用就进行累计,不会初始化):
1st close function 11
2nd close function 13
3rd close function 16
可以理解为:闭包是一个类,函数是操作,外部变量是字段
在函数中,我们经常需要创建资源(如,数据库连接 / 文件句柄 / 锁等),为了在函数执行完毕后,可以及时释放资源,Go框架设计了defer。
Note:
示例:
package main
import "fmt"
func sum(num1 int, num2 int) int {
defer fmt.Println("defer1 num1=", num1) //暂时不执行,压进defer栈中
defer fmt.Println("defer2 num2=", num2)
res := num1 + num2
fmt.Println("resFun=", res)
return res
}
func main() {
res := sum(10,20)
// 当函数执行完毕后,defer按照先进后出的方式出栈
fmt.Println("res=",res)
}
运行结果:
resFun= 30
defer2 num2= 20
defer1 num1= 10
res= 30