Golang的学习笔记(10)--Go函数
目录
Go函数
函数是基本的代码块,它的作用是可以将实现某个功能的多行代码封装到一段代码块中(即函数),在需要的时候去调用。同个函数可以被多次调用,实现代码重用。
函数一般会有参数和返回值(也可以没有),函数名称、函数参数、函数返回值以及它们的类型被统称为函数签名
在Go语言中,函数有以下一些特点:
- 支持不定长变参、多返回值、命名返回值参数
- 支持匿名函数、闭包
- 函数可以作为一种类型使用
- Go函数不支持嵌套、重载
Go函数定义
Go函数定义格式如下:
func function_name ([parameter list]) [return_type]{
函数体
}
funcparameter listparam1 type1, param2 type2...return_typeret1 type1函数值传递与引用传递
Go函数被调用的时候,传入的参数会被复制然后传递到函数内部使用,即函数体中使用的是参数副本。这种方式也称之为值传递
&slicemapGo函数的各种使用形式
returnfunc main(){
r1, r2 := A(1, "A")
}
func A(a int, b string) (int, string) {
c := a + 1
d := b + "aa"
return c, d
}
- 多个参数如果类型相同,可以合并写法,单个返回值可以不写括号
func main(){
r3 := B(1, 2, 3)
}
func B(a, b, c int) int {
return a + b + c
}
returnfunc main(){
r4, r5, r6 := C()
}
func C() (a, b, c int) {
a, b, c = 1, 2, 3
return
}
...typeslicefunc main(){
r7 := D(0,1,2,3)
}
func D(base int , s ...int) int {
for _, v := range s {
base += v
}
}
slicesliceslice- 传递指针参数(引用传递)
func main(){
p := 1
G(&p)
fmt.Println(p)
}
func G(p *int) {
*p = 2
fmt.Println(*p)
}
- 传递引用类型参数(引用传递)
func main(){
s := []int{1, 2, 3, 4}
F(s)
fmt.Println(s)
}
func F(s []int) {
s[0] = 5
s[1] = 6
s[2] = 7
s[3] = 8
fmt.Println(s)
}
- 函数作为一种类型来使用
func main(){
h := H
h()
}
func H() {
fmt.Println("H")
}
- 将函数调用的结果作为其它该函数的参数。只要只要这个被调用函数的返回值个数、返回值类型和返回值的顺序与调用函数所需求的实参是一致的
func main(){
r := f1(f2(5))
}
func f1(a,b,c int) int {
return a+b+c
}
func f2(a int) (b,c,d int){
b = a
c = a + 1
d = a - 1
return
}
- 将函数作为一种参数类型,即函数可以作为其它函数的参数进行传递,然后在其它函数内调用执行,一般称之为回调。注意和上一点进行区分
type cb func(int) int
func main() {
testCallBack(1, callBack)
testCallBack(2, func(x int) int {
fmt.Printf("我是回调,x:%d\n", x)
return x
})
}
func testCallBack(x int, f cb) {
f(x)
}
func callBack(x int) int {
fmt.Printf("我是回调,x:%d\n", x)
return x
}
匿名函数
匿名函数,顾名思义即没有名字的函数。匿名函数不能独立地定义,它需要赋值给某个变量,即保存函数的地址到变量中,然后通过变量对函数进行调用。或者定义的同时直接调用
func main(){
i := func(){
fmt.Println("匿名函数赋值给变量再调用")
}
i()
func(){
fmt.Println("匿名函数直接调用")
}()
}
Go的匿名函数支持闭包。关于闭包的概念:
闭包函数:声明在一个函数中的函数,叫做闭包函数
闭包:闭包函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回之后
closurex1112func main(){
f := closure(10)
fmt.Println(f(1))
fmt.Println(f(2))
}
func closure(x int) func(int) int {
return func(y int) int {
return x + y
}
}
defer 函数
deferdeferdeferdeferdeferdeferfunc main(){
for i := 0; i < 3; i++ {
defer fmt.Println(i) //将逆序输出 2 1 0
}
}
defertry-catchpanic-recoverpanicrecoverdeferrecoverdeferpanicfunc main(){
beforePanic()
panicRecover()
afterPanic()
}
func beforePanic() {
fmt.Println("before panic")
}
//panic-recover
func panicRecover() {
defer func() {
if err := recover(); err != nil {
fmt.Println("Recover in this")
}
}()
panic("Panic !!!")
}
func afterPanic() {
fmt.Println("after panic")
}