函数的定义和 函数的调用
package main import "fmt" func main() { sayHelloWorld() fmt.Printf("%T \n", sayHelloWorld) // func() ,是一个函数 sayHi("张三") // 你好 张三 ,实参 fmt.Println(add(1,5)) // 6 } // 定义一个函数 // 参数 // 返回值 func bublo_sort(heights []int) { //先把最高的人排到最后 for i := 0; i < len(heights); i++ { for j := i + 1; j < len(heights); j++ { if heights[i] > heights[j] { heights[i], heights[j] = heights[j], heights[i] } } } } //定义函数 ,定义一个无参,无返回值的函数 func sayHelloWorld() { fmt.Println("hello world!") } func sayHi(name string) { //形参 fmt.Println("你好 " + name) } func add (a int ,b int ) int { return a + b }
函数的定义及使用
package main import "fmt" func main() { a, b, c, d := calc1(1, 2) fmt.Println(a, b, c, d) sum, sub, mul, div := calc2(2, 1) //3 1 2 2 fmt.Println(sum, sub, mul, div) } //函数的返回值有多可,可以用多个变量去接收到 func calc1(a, b int) (int, int, int, int) { return 1, 2, 3, 4 } func calc2(a, b int) (sum int, sub int, mul int, div int) { sum = a + b sub = a - b mul = a * b div = a / b return }
函数的递归
package main import "fmt" func main() { fmt.Println(sumx(100)) // fmt.Println(mulx(9)) // 324 tower("A","B","C",3) } // 递归 100 + ... + 1 func sumx(index int) int { if index <= 1 { return 1 } return index + sumx(index-1) } // n ! func mulx(index int) int { if index <= 1 { return 1 } return index * sumx(index-1) } // 1个盘子 1 -C 1 // 2个盘子 1 -> B ,2 -> C ,1 -> C 3 // 3个盘子 1->C 2->B ,1 -> B , 3 -> C , 1-> A ,2 -> C ,1 -> C 7 , // 4个盘子 1 -> B , 2 -> C , 1 -> C , 3 -> B , 1 - > A , 2 -> B ,1 -> B , 4 -> C , 1 -> C , 2 -> A ,1 -> A , 2 -> C , 1 -> B , 2 -> C , 1 -> C , 15 // 汉诺塔游戏 func tower(a, b, c string, lay int) { if lay == 1 { fmt.Println(a, "->", c) return } tower(a,c,b,lay-1) fmt.Println(a ,"->",c) tower(b,a,c,lay -1 ) }
匿名函数
package main import "fmt" func main() { fmt.Printf("%T\n", fsum) // func(int, int) int var f func(int, int) int = fsum fmt.Println(f(1, 2)) printx(list, "1", "2", "3") // 1 2 3 // 定义一个匿名函数 sayHello1 := func (name string) { fmt.Println("hello ", name) } sayHello1("kka") //匿名函数只调用一次的情况下使用 func (name string){ // hahah fmt.Println(name) }("hahah") values := func(args ...string) { for _,v := range args { fmt.Println(v) } } printx(values,"A","B","C") } func fsum(a, b int) int { return a + b } // callback格式 ,将传递的数据按照每行打印 还是按照一行一行打印 func printx(callback func(...string), args ...string) { fmt.Println("print函数的输出 :") callback(args...) } func list(args ...string) { for _, v := range args { fmt.Printf("%s \t", v) } }
闭包
package main import ( "fmt" ) func main() { add2 := func(n int) int { return n + 2 } fmt.Println(add2(2)) add10 := func(n int) int { return n + 10 } fmt.Println(add10(10)) // 闭包问题 addbase := func(base int) func(int) int { // 返回一个函数 return func(n int) int { return base + n } } fmt.Println(addbase(8)(10)) // 18 fmt.Printf("%T \n",addbase(8)) // 返回一个函数 add4 := addbase(4) add8 := addbase(8) add11 := addbase(11) fmt.Println(add4(4)) //8 fmt.Println(add8(4)) // 12 fmt.Println(add11(4))//15 }
7.值类型与引用类型和值传递
在Go语言中参数传递默认均以值传递(形参为实参变量的副本),对于引用类型的数据因为其底层共享数据结构,所以在函数的内可以引用类型数据修改从而影响函数外的原来变量的信息。
package main import "fmt" func main() { array:= [3]string{"A","B","C"} slice := []string{"A","B","C"} arrayA := array sliceA := slice arrayA[0] = "D" sliceA[0] = "D" fmt.Println(array ,arrayA == array) //值类型 //值类型,引用类型 // 将变量赋值给新的一个变量,如果对变量有影响,引用类型,如果对变量没有影响,就是值类型 fmt.Println(slice) // int ,bool,float32 ,float64 ,array ,slice ,map // int ,bool,float32 ,float64 ,array,结构体 值类型 // slice ,map ,接口,引用类型 // 指针是一个值类型 m := map[string]string{} mA := m mA["kk"] = "张天" fmt.Println(m) // map[kk:张天] //通过指针来改值 age :=30 b := &age *b = 20 fmt.Println(age,*b) fmt.Printf("%p %p \n", & age ,& b )// 0xc0000b2020 0xc0000ac020 fmt.Printf("%p %p \n", slice ,sliceA ) // 0xc000098180 0xc000098180 fmt.Printf("%p %p \n", & slice[0] ,& sliceA[0] )// 0xc000098180 0xc000098180 fmt.Printf("%p %p \n", & array,&arrayA ) // 0xc00006e180 0xc00006e1e0 }
针对值类型和引用类型在赋值后新旧值的地址并不相同,只是引用类型在底层的共享数据结构(其中包含指针类型的元素 )
值类型数据结构 :
引用类型数据结构:
package main import "fmt" func changeInt(a int) { a = 100 } func changeSlice(s []int) { s[0] = 100 } func changeIntAddress(n *int) { *n = 2 } // 修改地址的地址对应的值 func changeIntAddressAddresss(n **int) { **n = 10 } func main() { num := 1 changeInt(num) fmt.Println(num) // 1 ,按值传递,是不会修改外面的值 nums := []int{1, 2, 3} changeSlice(nums) fmt.Println(nums) // [100 2 3] ,引用类型的数据是会修改外面的数据的 changeIntAddress(&num) fmt.Println(num) // 2 num2 := &num changeIntAddressAddresss(&num2) fmt.Println(num) // 10 }
错误处理
需要自己处理错误信息
package main import ( "errors" "fmt" ) func div(a, b int) (int, error) { if b == 0 { return -1, errors.New("div by zero") } return a / b, nil } //返回值,怎样定义错误类型 // 怎么创建错误类型对应的值信息 func main() { //num := 1 / 0 //fmt.Println(num) // ./error1.go:6:11: division by zero fmt.Println(div(1, 0)) e := fmt.Errorf("error %s ","div by zero") fmt.Printf("%T ,%v \n",e ,e) // *errors.errorString ,error div by zero }
延迟执行
defer关键字用户声明函数,不论函数是否发生错误都在函数执行最后执行(return) 若使用defer声明多个函数,则按照声明的顺序,先声明执行(堆)常用来做资源释放,记录日志等工作
常用来做资源释放,记录日志的工作
panic 和recover函数
go语言提供了panic和recover函数用于处理运行时错误,当调用panic抛出错误,中断 有的控制流程,常用于不可以修复的错误,recover函数用于终止错误处理流程,仅在defer语句的函数中有效,用于截取处理流程,recover只能捕获最后一个错误处理
panic
package main import "fmt" func main() { // 当函数退出的时候执行 defer func() { fmt.Println("defer2") }() defer func() { fmt.Println("defer2") }() fmt.Println("main over ") //main over //xxx }
异常处理:
package main import ( "fmt" ) func testxx() (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("%v", e) } }() panic("error___________________") } func main() { err := testxx() fmt.Println(err) /*defer func() { fmt.Println() if err := recover(); err != nil { fmt.Println(err) fmt.Println("恢复处理") } }() fmt.Println("main start ") panic("error xxx") fmt.Println("over") */ }
命令行用户管理
用户信息存储
=> 内存 [] map
=>存储结构 id name age tel addr [len] [] map 值类型都用string类型
用户添加
用户删除
用户查询
package main import ( "fmt" "os" "strconv" "strings" ) //添加用户 func addx(users map[string]map[string]string) { start: var ( id string name string ) fmt.Println("请输入姓名或退出(q/Q):") fmt.Scan(&name) if name == "q" || name == "Q" { return } id = getmaxId(users) users[id] = map[string]string{ "id": id, "name": name, } fmt.Println(users) goto start } func getmaxId(users map[string]map[string]string) string { maxId := 1 for k, _ := range users { if i, err := strconv.Atoi(k); err == nil { if maxId < i { maxId = i } } } maxId = maxId + 1 return strconv.Itoa(maxId) } func inputString(prompt string) string { fmt.Println(prompt) var inputId string fmt.Scan(&inputId) return strings.Trim(inputId, " ") } //更新用户 func updatex(users map[string]map[string]string) { fmt.Println("请输入要修改用户姓名:") var inputId string fmt.Scan(&inputId) xx := strings.Split(inputId, "_") fmt.Println(xx) for k, v := range users { for _, name := range v { if strings.Contains(name, xx[0]) { users[k]["name"] = xx[1] break } } } } //删除用户 func deletex(users map[string]map[string]string) { start: fmt.Println("请删除用户姓名:") var inputId string fmt.Scan(&inputId) if inputId == "q" || inputId == "Q" { return } if inputId == "all" { for k, _ := range users { delete(users, k) } } else { for k, v := range users { for _, name := range v { if strings.Contains(name, inputId) { delete(users, k) break } } } } goto start } // func queryx(users map[string]map[string]string) { start: fmt.Println("请输入要查询的用户姓名或退出(q/Q):") var inputId string fmt.Scan(&inputId) if inputId == "q" || inputId == "Q" { return } if inputId == "all" { for _, v := range users { fmt.Printf("%5s|%20s\n", v["id"], v["name"]) } } else { for _, v := range users { for _, name := range v { if strings.Contains(name, inputId) { fmt.Printf("%5s|%20s\n", v["id"], v["name"]) break } } } } goto start } const ( maxAuth = 3 password = "132" ) // 从命令行中输入值 func auth() bool { var input string fmt.Println("请输入密码:") for i := 0; i < maxAuth; i++ { fmt.Scan(&input) if input == password { return true } else { fmt.Println("你的密码错误,请重新输入:") } } return false } func main() { if !auth() { fmt.Println("你的密码错误") return } callbacks := map[string]func(map[string]map[string]string){ "1": addx, "2": updatex, "3": deletex, "4": queryx, } fmt.Println(callbacks) //存储用户信息 users := make(map[string]map[string]string) fmt.Println("欢迎使用用户管理系统:") //id := 0 for { var op string fmt.Println(`请输入指令: 1.新建用户 2.修改用户 3.删除用户 4.查询用户 q.退出`) fmt.Scan(&op) if "q" == op { //return os.Exit(500) //直接退出 } callbacks[op](users) /*switch op { case "1": id++ addx(&id, users) break case "2": updatex(users) break case "3": deletex(users) break case "4": queryx(users) break case "q": return default: break }*/ } }
github地址是