直接上代码。
/**流程和函数**/package mainimport ( . "fmt" // "os")func main() { // testIf() // testGoto() // testFor() // testSwitch() // year, str := demo("Chris", 24, 2014, "demoFunc") // Println(year, str) // demoArgs(1, 2, 3, 4, 5, 6, 7, 8, 9, 0) //传指针 // a := 1 // Printf("a:%d\n", a) // a1 := demoTest(&a) //传入指针 然后再累加,其实a 和 a1 的内存地址都是一样的 // Printf("a1 = a+1 = %d\n", a1) // Printf("a = %d\n", a) //defer // demoDefer() // demoDefer() //函数作为值、类型传递 // testFilter() //异常处理 throwsPanic(T)}/关于程序异常处理:Panic 和 Recover机制 ,相当于 panic抛出异常, defer 和 recover捕获异常func T() { // defer func() { // Println("defer func is run") // r := recover() // if r != nil { // Println("recover : ", r) // } // }() // Println("body") // panic("panic is run") // Println("body 2") n := 1 if n > 0 { panic("this n > 0!") } Println("end T()")}//func throwsPanic(fun func()) (b bool) { defer func() { Println("defer func is run") if r := recover(); r != nil { Println("recover:", r) b = true } }() fun() return}函数作为值、类型:函数当做值和类型在我们写一些通用接口的时候非常有用func testFilter() { //测试函数作为值、类型传递 slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} Println("slice=", slice) evenNumber := filter(slice, isEvenNumber) //isEvenNumber函数当作值来传递 Println("evenNumber=", evenNumber) oddNumber := filter(slice, isOddNumber) Println("oddNumber=", oddNumber)}func filter(slice []int, fun filterInt) []int { var result []int for _, val := range slice { //循环数组 if fun(val) { result = append(result, val) } } return result}type filterInt func(int) bool //声明一个函数类型func isEvenNumber(n int) bool { //实现函数类型,判断是否为偶数 if n%2 == 0 { return true } return false}func isOddNumber(n int) bool { //实现函数类型,判断是否为奇数 if n%2 == 0 { return false } return true}/自定义函数/**1、关键字func用来声明一个函数funcName2、函数可以有一个或者多个参数,每个参数带有类型,通过,分割3、函数可以有多个返回值,可以自定义返回值的变量只需return就自动返回,建议自定义返回值变量4、如果只有一个返回值且不声明返回值变量,那么可以省略写成返回值类型5、如果有返回值,那么必须在函数外层添加return语句**/func demo(name string, age, year int, val string) (add int, say string) { say = Sprintf("\nName:%s \nAge:%d \nVal:%s", name, age, val) add = year + age return}//变参:可变参数的类型都是相同的func demoArgs(args ...int) { for _, n := range args { Printf("int arg is:%d\n", n) }}/**关于传值和传指针,调用一个函数传入参数实际上是传入的copy的变量,变量在函数内变化不影响外部的变量值。传引用 即 传入指针则会影响外部变量的值传指针1、传指针使多个函数能够操作同一对象2、传指针比较轻量级(8bytes),只传内存地址,可以用指针传递体积大的结构体。如果用参数值传递的话,在每次copy上就会花费相对较多的系统开销。当要传递处理大的结构体的时候,用指针3、go中string、slice、map三种类型的实现机制类似指针,所以可以直接传递而不用取地址后传递指针。(若函数需要改变slice长度,则仍需要取地址传递指针)**/func demoTest(a *int) int { //传入指针类型,也就相当于copy传入变量的指针,通过指针修改变量就可影响外部变量 Println("a的指针地址是", a) //这里a为指针地址 *a为指针地址对应的值 *a = *a + 1 return *a //返回指针的变量}//延迟语句 defer。函数中可以定义多个defer,将会在函数每次执行完毕后按代码顺序逆序执行//特别用在一些资源访问时,当出错了可以做关闭资源的收尾工作,防止资源泄露func demoDefer() { // f, err := os.Open("demo.php") // defer f.Close() // if err != nil { // Println("err != nil") // } // Println(f, err) //如果多次调用defer,defer是栈后进先出。 defer Println("\nstart defer") for i := 0; i < 5; i++ { defer Printf("%d", i) } defer Println("\nend defer")}/func testSwitch() { i := 10 switch i { case 1: Println("i =", i) case 2, 4, 5: Println("i in (2,4,5) = ", i) case 10: Println("i is 10~ i=", i) fallthrough // 强制向下执行 default: Println("default case") }}func testIf() { x := 20 if x > 10 { Println("x > 10 and x=", x) } else { Println("x <= 10 and x=", x) } if y := 10; y > 10 { //声明一个仅用于if逻辑中的变量(作用域在if中) Println("y>10") } else { Println("y<=10") } //Println(y)//这里就得不到变量y的值 //多条件 if x <= 10 { Println("x<=10") } else if x > 10 && x < 20 { Println("x>10 and x<20") } else { Println("x >=20") }}func testGoto() { //goto 的标签必须在当前函数内,实现一个循环 i := 0Here: //此行开头,大小写敏感,以冒号作为结束结束标签 Println(i) i++ if i <= 10 { goto Here } Println("结束")}func testFor() { sum := 0 for i := 0; i < 10; i++ { if i == 7 { //跳出整个循环 break } else if i == 4 { //跳出本次循环 continue } sum += i Println(i, sum) } Println("----------------")}