Golang 学习中对函数的学习心得
在近期开始学习 Go 语言的过程中,发现 Go 语言中函数的作用和函数的使用,与过去在学校学习的 C 语言以及 python 中所使用的方式很不一样(也可能只是我才疏学浅),所以记录一下 Go 语言的函数学习心得。
1、函数的本质
在 Go 语言中,函数的本质是一种数据类型,就如同 int,float,string 一样,函数作为一种数据类型而存在。因此同其他的数据类型一样,函数也可以进行赋值等操作。注意,虽然函数是一种数据类型,但不同的函数不一定相等。必须传递的变量数量,变量类型相同,返回的数据类型相同(或者都不返回值)才能说这两个函数是相同的数据类型。其次,不同的变量,赋值同一个函数,会发现它们会指向同一个内存地址,例如以下代码中
package main
import "fmt"
func main() {
var x func(int, int) int
x = f1
var y func(int, int) int
y = f1
fmt.Println(x)
fmt.Println(y)
fmt.Println(f1)
}
func f1(a, b int) int {
return a + b
}
最后的输出为:
0x75df20
0x75df20
0x75df20
表明它们指向同一个地址。并且其中 x,y 都具有了函数 f1 的功能
2、匿名函数的推导
函数作为一种数据类型,同 GO 语言中的其他数据类型一样,可以进行推导,并不是必须注明变量类型,GO 会自动推导数据类型。而匿名函数可以自己调用自己,可以传递参数,可以输出参数,且只会调用一次,例如以下代码
package main
import (
"fmt"
)
func main() {
func() {
fmt.Println("我是无参无返回值匿名函数")
}()
func(a, b int) {
fmt.Printf("我是有参无返回值匿名函数,我会的输出参数是:%d,%d \n", a, b)
}(1, 2)
var ans int
ans = func(a, b int) int {
fmt.Print("我是有参有返回值匿名函数我将会返回a+b的结果:")
return a + b
}(1, 2)
println(ans)
}
输出结果为:
我是无参无返回值匿名函数
我是有参无返回值匿名函数,我会的输出参数是:1,2
我是有参有返回值匿名函数我将会返回a+b的结果:3
3、回调函数
函数既然作为一种变量类型,自然也可以作为另一个函数的参数使用,这就是回调函数。例如以下代码
package main
func main() {
println(f1(1, 2, add))
}
func f1(a, b int, fun func(int, int) int) int {
r := fun(a, b)
return r
}
func add(a, b int) int {
return a + b
}
返回结果为:3
甚至输入的参数可以为匿名函数
4、闭包
闭包是在回调函数的基础上产生的,闭包是指在当一个函数 A 其返回值为一个函数 B 时,并且函数 A 中的变量在 B 中有使用时,这时候变量的生命周期就会发生变换(一般情况下 GO 的变量作用域遵循就近原则),即当外层函数被销毁时,其变量仍旧存在,例如以下代码
package main
func main() {
a1 := abc()
println(a1())
println(a1())
println(a1())
println(a1())
println()
a2 := abc()
println(a2())
println(a2())
println(a2())
println(a2())
println()
println(a1())
println(a2())
}
func abc() func() int {
var i int
i = 0
f := func() int {
i++
return i
}
return f
}
最后的输出为:
1
2
3
4
1
2
3
4
5
5
可以发现即便外层函数销毁以后,i 仍旧保留在内层函数中并且一直存在,即使重新定义了新的 abc 函数并使用它的内层函数。这种现象就是闭包,这是回调函数所独有的
5、总结
GO 语言中的函数非常特别,所以也有说法说 GO 是 “函数式的编程”,函数作为一种变量类型而存在,这种特殊性给了 GO 在使用函数的过程中更多地可能性,利用好这种函数的特殊性可以更好地帮助使用者完成特定的任务。
(人生的第一篇博客,如有问题还望指出😣)
var code = "762dd525-28ba-4196-ba15-6eb1f2bf2425"