版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kang___xi/article/details/86530488
Go语言的函数声明以func标识,后面紧接着函数名、参数列表、返回参数列表以及函数体。
1.普通函数的声明形式
func 函数名(参数列表) (返回参数列表){
//函数体
}
注意:
在同一个包内,函数名不能相同
参数列表中如果多个参数类型相同,则可放在一起声明。如func test(a, b int) {}同时声明a, b为int类型
函数可以同时返回多个值
2.同一类型返回值
func typedTwoValues() (int, int) {
return 1, 2
}
a, b = typedTwoValues()
fmt.Println(a, b)
3.带有变量名的返回值
func namedRetVallues() (a, b int) {
a = 1
b = 2
return
}
当函数使用命名返回值时,可以在return中不填写返回值列表,如果填写也是可行的。
4.参数传递
Go语言中传入和返回参数在调用和返回时都使用值传递,这里要注意的是指针、切片和map等引用型对象指向的内容在参数传递中不会发生复制,而是将指针进行复制,类似于创建一次引用。
5.函数变量
在Go语言中,函数也是一种类型,可以和其他类型一样被保存在变量中。
func fire() {
fmt.Println("call fire")
}
func foo1(a int) int{
}
var f1 func() //定义函数变量f,无参无返回值
f1 = fire
var f2 func(int) int = foo1
6.匿名函数
Go语言支持匿名函数,即在需要使用函数时,再定义函数,匿名函数没有函数名,只有函数体,函数可以被作为一种类型赋值给函数类型的变量,匿名函数也往往以变量方式被传递。
匿名函数经常被用于实现回调函数、闭包等。
(1)匿名函数定义格式
func(函数列表) (返回参数列表) {
//函数体
}
(2)定义时调用匿名函数
func(data int) {
fmt.Println("hello", data)
}(100)
(3)将匿名函数赋值给变量
f := func(data int) {
fmt.Println(data)
}
f(100) //调用匿名函数
(4)匿名函数作为回调函数
func visit(list []int, f func(int)){
//to do
for _, v := range list {
f(v)
}
}
visit([]int{1, 2, 3}, func(data int) {
fmt.Println(data)
})
(5)匿名函数实现操作封装
var skill = map[string]func() {
"fire":func() {
fmt.Println("chicken fire")
},
"run":func() {
fmt.Println("soldier run")
},
}
7.变参函数
所谓可变参数,是值参数数量不固定的函数形式。Go语言支持可变参数特性,函数声明和调用时没有固定数量的参数。
(1)变参函数定义格式
func 函数名(固定参数列表, v ... T) (返回参数列表) {
//todo
}
可变参数一般被放置函数列表的末尾,前面是固定参数列表
v为可变参数变量,类型为[]T
T为可变参数的类型,如果T为interface{},传入的可以是任意类型
(2)所有参数都是可变参数
以fmt.Println()为例:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
(3)部分参数是可变参数
以fmt.Printf()函数为例:
func Printf(format string, a ...interface{}) (n int, err error) {
return Fprintf(os.Stdout, format, a...)
}
(4)在多个可变参数函数中传递参数
func rawPrint(rawList ...interface{}) {
//todo
}
func Print(slist ...interface{}) {
rawPrint(slist...) //这种用法在切片的append()中也见过
}
func main() {
Print("hello", 123)
}
8.defer(延迟执行语句)
Go语言的defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer的逆序进行执行。也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。
func main() {
defer fmt.Println("defer begin")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
defer fmt.Pritnln("defer end")
}
输出结果:
defer begin
defer end
3
2
1
通过defer声明调用的函数的调用顺序和C++析构的调用函数类似,都是一个栈的调用顺序、