::: hljs-center
:::
::: hljs-center
Go语言基础
:::
++Go语言的优势++ 1.高性能,高并发 拥有和java,c++相媲美的性能,内嵌了对高并发的支持(不需引入第三方库)
2.语法简单,学习曲线平缓 如下仅用十行代码即实现了可承载静态访问,支持高并发的服务器
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport ( "net/http" ) func main () { http.Handle("/" ,http.FileServer(http.Dir("." ))) http.ListenAndServe(":8080" ,nil ) }
3.丰富的标准库 go提供大量强大的标准库,很多时候不需要使用第三方库即可实现复杂的功能,大大降低了学习成本
4.完善的工具链 包括包管理,ide等完善稳定的工具
5.静态编译 在go语言中,默认所有结果都是静态链接的,只需拷贝编译后的一个唯一文件即可部署运行,镜像体积可以控制的非常小,部署方便快捷。
6.快速编译 拥有静态语言中最快速的编译速度,在字节跳动大量的微服务在线上部署之前编译时间小于一分钟,在真正本地开发的时候,修改完一行代码都能在一秒钟之内增量编译完成
7.跨平台 8.垃圾回收 go语言带有类似java的垃圾回收能力,写代码时只需专注业务逻辑,无需考虑内存释放
++Go的基础语法++ go的hello world go的helloworld长这样:
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport ( "fmt" ) func main () { fmt.Println("hello world" ) }
在硬盘中以main.go保存,想直接运行程序使用
go run main.go
go支持直接编译成二进制运行,使用
go build main.go
随后输入
./main
不出意外将输出
hello world
变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport "fmt" func main () { var a = 1 var b int = 2 text := "hello world" const pi float64 = 3.14 fmt.Println(text, a, b, pi) }
if-else 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport "fmt" func main () { if 7 %2 == 0 { fmt.Println(7 , "is even" ) } else { fmt.Println(7 , "is odd" ) } if num := 9 ; num >= 0 { fmt.Println("9 >= 0" ) } else if num <= 10 { fmt.Println("9 <=10" ) } }
循环 go中没有while,do while等,只有for循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport "fmt" func main () { for { fmt.Println("hhh" ) } for i := 0 ; i < 3 ; i++ { fmt.Println(i) } for n:=0 ;n<5 ;n++{ if (n==2 ) { continue ; } fmt.Println(n) } }
switch 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package mainimport ( "fmt" "time" ) func main () { a := 2 switch a { case 1 : fmt.Println("one" ) case 2 : fmt.Println("two" ) case 3 : fmt.Println("three" ) case 4 , 5 : fmt.Println("four or five" ) default : fmt.Println("other number" ) } t := time.Now() switch { case t.Hour() < 12 : fmt.Println("it's before noon" ) default : fmt.Println("it's after noon" ) } }
切片 在真正业务逻辑中很少使用数组,更多使用的是 切片 切片相较于数组长度不可变的局限性,你可以任意的去更改它的长度,拥有更多丰富的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport "fmt" func main () { s := make ([]string , 3 ) s[0 ] = "a" s[1 ] = "b" s[2 ] = "c" fmt.Println("get" , s[2 ]) s = append (s, "d" ) fmt.Println(s) c := make ([]string , len (s)) copy (c, s) fmt.Println(c) fmt.Println(s[0 :2 ]) fmt.Println(s[:4 ]) }
map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package mainimport "fmt" func main () { m := make (map [string ]int ) m["apple" ] = 10 m["pen" ] = 20 fmt.Println(m["pen" ]) r, contains := m["apple" ] fmt.Println(r, contains) }
range 对于切片或map,可以使用range来快速遍历。这样代码将更加简洁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package main import "fmt" func main() { var arry [5]int arry[0] = 1 arry[1] = 2 arry[2] = 3 arry[3] = 4 arry[4] = 5 //输出结果: //idx= 0 value= 1 //idx= 1 value= 2 //idx= 2 value= 3 //idx= 3 value= 4 //idx= 4 value= 5 for idx, value := range arry { fmt.Println("idx=", idx, " value=", value) } m := make(map[string]int) m["apple"] = 10 m["pen"] = 5 for k, v := range m { fmt.Println("item=", k, " price=", v) } }
函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package mainimport "fmt" func add (a int , b int ) int { return a + b } func add0 (a, b int ) int { return a + b } func exists (m map [string ]string , k string ) (value string , contains bool ) { v, ok := m[k] return v, ok } func main () { res := add(1 , 2 ) fmt.Println(res) value, contains := exists(map [string ]string {"a" : "A" }, "a" ) fmt.Println(value, contains) }
指针 go也初步支持指针,但远没有c那样强大,以下是一个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package mainimport "fmt" func add2 (n int ) { n += 2 } func add2ptr (n *int ) { *n += 2 } func main () { n := 2 add2(n) fmt.Println(n) add2ptr(&n) fmt.Println(n) }
结构体 类似java中的类对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport "fmt" type user struct { name string password string } func (u *user) resetPassword(newpassword string ) { u.password = newpassword } func main () { a := user{name: "zsh" , password: "1024" } b := user{name: "zyy" } b.password = "1024" fmt.Println(a.name, "password: " , a.password) a.resetPassword("zyy i love u" ) fmt.Println(a.password) }
异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package mainimport ( "errors" "fmt" ) type user struct { name string password string } func findUser (users []user, name string ) (v *user, err error ) { for _, u := range users { if u.name == name { return &u, nil } } return nil , errors.New("not found" ) } func main () { u, err := findUser([]user{{"zsh" , "1024" }}, "zsh" ) if err != nil { fmt.Println(err) return } fmt.Println(u.name) }
字符串操作 strings下包含了许多对字符串的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package mainimport ( "fmt" "strings" ) func main () { text := "zsh" fmt.Println(strings.Contains(text, "zs" )) fmt.Println(strings.Contains(text, "zyy" )) fmt.Println(strings.Count(text, "z" )) fmt.Println(len (text)) fmt.Println(len (text)) fmt.Println(strings.Split(text, "-" )) }
JSON处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "encoding/json" "fmt" ) type user struct { idx int `json:"idx"` Name string Password string } func main () { zsh := user{idx: 1 , Name: "zsh" , Password: "1024" } buf, err := json.Marshal(zsh) if err != nil { panic (err) } fmt.Println(buf) fmt.Println(string (buf)) var zshCpy user json.Unmarshal(buf, &zshCpy) fmt.Println(zshCpy.Name) }
时间处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package mainimport ( "fmt" "time" ) func main () { now := time.Now() fmt.Println(now) t := time.Date(2022 , 1 , 1 , 20 , 20 , 30 , 0 , time.UTC) fmt.Println(t.Year()) diff := now.Sub(t) fmt.Println(diff) fmt.Println(now.Unix()) }
字符串与数字的转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package mainimport ( "fmt" "strconv" ) func main () { f, _ := strconv.ParseFloat("1.234" , 64 ) fmt.Println(f) n, _ := strconv.ParseInt("10" , 10 , 64 ) fmt.Println(n) n2, _ := strconv.Atoi("123" ) fmt.Println(n2) }
进程信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package main import ( "fmt" "os" ) func main() { //使用命令 go run main.go a b c d //输出: //[C:\Users\hasee\AppData\Local\Temp\go-build580179449\b001\exe\main.exe a b c d] //第一个参数为二进制文件地址 接下来是args fmt.Println(os.Args) //获取环境变量 fmt.Println(os.Getenv("PATH")) //写入环境变量 fmt.Println(os.Setenv("zsh", "1024")) }
++小结++ 标准库
fmt 提供格式化输入输出os 提供与操作系统交互的函数string 提供字符串操作的函数net 提供网络编程的函数strconv 提供数字与字符之间的转换操作time 时间处理encoding/json json的相关操作
一个练习的小项目,二分查找猜谜游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package mainimport ( "bufio" "fmt" "math/rand" "os" "strconv" "strings" "time" ) func main () { rand.Seed(time.Now().UnixNano()) maxNum := 100 rNumber := rand.Intn(maxNum) fmt.Println("Please input your anser" ) reader := bufio.NewReader(os.Stdin) for { input, err := reader.ReadString('\n' ) if err != nil { fmt.Println(err) return } input = strings.TrimSuffix(input, "\r\n" ) guess, err := strconv.Atoi(input) if err != nil { fmt.Println("error input,it not is number" ) return } fmt.Println("your guess is" , guess) if guess > rNumber { fmt.Println("你输入的数字大于答案,请再次输入" ) } else if guess < rNumber { fmt.Println("你输入的数字小于答案,请再次输入" ) } else { fmt.Println("Accept!" ) break } } }
系统会预生成一个[0,100)的随机数 用户通过连续的输入将得到 “输入的数大于答案” or “输入的数小于答案” 直到猜测正确完成游戏