package main; import "fmt" func main() { a, b, c := A(1, 2, 3); fmt.Println(a, b, c); //调用函数B,虽然传入的是一个slice,但外部变量并未改变,说明是值拷贝 B(a, b, c); fmt.Println(a, b, c); d := []int{1, 2, 3}; //这里传入的是一个slice,但外部变量确改变了,说明是地址拷贝。 C(d); fmt.Println(d); e := 2; //这里把e的地址传递过去 D(&e); fmt.Println(e); //函数E赋值给f f := E; f(); //匿名函数 g := func() { fmt.Println("我是匿名函数"); }; g(); //使用闭包 h := F(66); //两次调用都使用了66 fmt.Println(h(66)); fmt.Println(h(88)); //调用G函数,defer反向调用 G(); H(); //调用I函数 I(); } //GO函数不支持嵌套,重载和默认参数 //定义函数 //func 函数名(参数列表) (返回值) {函数体} func A(a int, b int, c int) (int, int, int) { return a * 2, b * 2, c * 2; } //不定长变参,必须作为参数列表最后的参数 //传入的是一个slice func B(a ...int) { for k := range a { a[k] = a[k] * 2; } } //传递slice func C(a []int) { for k := range a { a[k] = a[k] * 2; } } //传递指针 func D(a *int) { *a = 6; } //函数也是一个类型 func E() { fmt.Println("func E"); } //闭包 //返回值是一个函数 func F(a int) (func(int) int) { //打印a的地址 fmt.Printf("%p\n", &a); return func(b int) int { fmt.Printf("%p\n", &a); return a + b; }; } //defer执行方式类似其它语言中的析构函数 //在函数体执行结束后,按照调用顺序的相反顺序逐个执行 //常用于资源清理,文件关闭,解锁 func G() { defer fmt.Println(1); defer fmt.Println(2); defer fmt.Println(3); } func H() { for i := 0; i < 3; i++ { //这里用到了闭包 defer func() { //这里的i作为地址的引用,引用局部变量i //函数体结束后,i的值就变成了3,所以打印三次3 fmt.Println(i) }(); } //这里的输出就跟上面的不一样,输出2,1,0 for i := 0; i < 3; i++ { //这里是作为参数传递,是值的拷贝 defer func(a int) { fmt.Println(a); }(i); } } //GO里面没有异常机制,但有panic/recover来处理错误 //panic可以在任何地方引发,但recover只在defer调用的函数中有效 func I() { J(); K(); M(); } func J() { fmt.Println("fucn J"); } func K() { //defer必须在panic之前,因为panic之后函数不会执行了。 //通过recover对程序进行恢复 defer func() { if err := recover(); err != nil { fmt.Println("recover in func K"); } }(); panic("panic in func K"); } func M() { fmt.Println("func M"); }
版权声明:博主文章,可以不经博主允许随意转载,随意修改,知识是用来传播的。