Go语言初篇
目录
Go-开发环境
Go-语言基础
Go-标准库
Go-面向对象
Go-并发
Go-数据库
Go-web框架
Go语言开发文档:https://studygolang.com/pkgdoc
GO语言中文网:https://studygolang.com/
深度开源:https://www.open-open.com/
KanCloud看云:https://www.kancloud.cn/
Go资料:https://studygolang.com/articles/1450?fr=sidebar
个人资料:https://pan.baidu.com/s/1O9RLHCW9FXglYCRHWIslLA 密码:ebg8
Go-开发环境
GoLand IDE:https://www.jetbrains.com/go/
IDE破解:https://www.cnblogs.com/-wenli/p/10739315.html
文件相关快捷键: CTRL+E,打开最近浏览过的文件。 CTRL+SHIFT+E,打开最近更改的文件。 CTRL+N,可以快速打开struct结构体。 CTRL+SHIFT+N,可以快速打开文件。 代码格式化: CTRL+ALT+T,可以把代码包在一个块内,例如if{…}else{…}。 CTRL+ALT+L,格式化代码。 CTRL+空格,代码提示。 CTRL+/,单行注释。CTRL+SHIFT+/,进行多行注释。 CTRL+B,快速打开光标处的结构体或方法(跳转到定义处)。 CTRL+“+/-”,可以将当前方法进行展开或折叠。 查找和定位 CTRL+R,替换文本。 CTRL+F,查找文本。 CTRL+SHIFT+F,进行全局查找。 CTRL+G,快速定位到某行。 代码编辑 ALT+Q,可以看到当前方法的声明。 CTRL+Backspace,按单词进行删除。 SHIFT+ENTER,可以向下插入新行,即使光标在当前行的中间。 CTRL+X,删除当前光标所在行。 CTRL+D,复制当前光标所在行。 ALT+SHIFT+UP/DOWN,可以将光标所在行的代码上下移动。 CTRL+SHIFT+U,可以将选中内容进行大小写转化。
Go-语言基础
1.Hello World
package main import "fmt" func main() { fmt.Println("Hello, World!") } 让我们来看下以上程序的各个部分: 第一行代码 package main 定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。 下一行 import "fmt" 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。 下一行 func main() 是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有 init() 函数则会先执行该函数)。 下一行 /*...*/ 是注释,在程序执行时将被忽略。单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。 下一行 fmt.Println(...) 可以将字符串输出到控制台,并在最后自动增加换行字符 \n。 使用 fmt.Print("hello, world\n") 可以得到相同的结果。 Print 和 Println 这两个函数也支持使用变量,如:fmt.Println(arr)。如果没有特别指定,它们会以默认的打印格式将变量 arr 输出到控制台。 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
基础内容参考:
https://www.yiibai.com/go/go_start.html
https://www.kancloud.cn/liupengjie/go/570005
Go-标准库
1.os库使用
package main import ( "fmt" "os" ) func main(){ //获得当前工作目录:默认当前工程目录 dir,err := os.Getwd() fmt.Print(dir) fmt.Print(err) //获得指定环境变量 //paths := os.Getenv(key:"Path") //goroot := os.Getenv(key:"GOROOT") //fmt.Print(paths) //fmt.Print(goroot) //修改文件访问时间和修改时间 //err2 := os.Chtimes( // name:"", // time.Now().AddDate(years:-1,months:0,days:0) // ) //获得所有环境变量 envs := os.Environ() for _,env := range envs{ fmt.Print(env) } //在网络中的主机名 hostname,err := os.Hostname() if err == nil { fmt.Print(hostname) }else { fmt.Print("出错了") } //获得系统的临时文件夹路径:临时数据的保存路径 fmt.Print(os.TempDir()) //判断某字符是否路径分隔符 fmt.Print("//是路径分隔符吗?",os.IsPathSeparator('\\')) //fmt.Print("\\是路径分隔符吗?",os.IsPathSeparator(c:'\')) fmt.Print("$是路径分隔符吗?",os.IsPathSeparator('\\')) //fmt.Print(os.IsPathSeparator(c:'\\')) //fmt.Print(os.IsPathSeparator(c:'$')) //获得文件信息 fileInfo,err := os.Stat("C:/users/...") if err == nil { fmt.Print(fileInfo) }else { fmt.Print("出错了") } }
01: 获取当前时间 dateTime := time.Now() fmt.Println(dateTime) 02: 获取年 月 日 时 分 秒 纳秒 year := time.Now().Year() //年 fmt.Println(year) month := time.Now().Month() //月 fmt.Println(month) day := time.Now().Day() //日 fmt.Println(day) hour := time.Now().Hour() //小时 fmt.Println(hour) minute := time.Now().Minute() //分钟 fmt.Println(minute) second := time.Now().Second() //秒 fmt.Println(second) nanosecond := time.Now().Nanosecond() //纳秒 fmt.Println(nanosecond) 03: 获取当前时间戳 timeUnix := time.Now().Unix() //单位秒 timeUnixNano := time.Now().UnixNano() //单位纳秒 fmt.Println(timeUnix) fmt.Println(timeUnixNano) 04: 将时间戳格式化 fmt.Println(time.Now().Format("2006-01-02 15:04:05")) 05: 时间戳转为go格式的时间 var timeUnix int64 = 1562555859 fmt.Println(time.Unix(timeUnix,0)) // 之后可以用Format 比如 fmt.Println(time.Unix(timeUnix, 0).Format("2006-01-02 15:04:05")) 06: str格式化时间转时间戳 t := time.Date(2014, 1, 7, 5, 50, 4, 0, time.Local).Unix() fmt.Println(t) 时间的计算 01: 获取今天0点0时0分的时间戳 currentTime := time.Now() startTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location()) fmt.Println(startTime) fmt.Println(startTime.Format("2006/01/02 15:04:05")) 02: 获取今天23:59:59秒的时间戳 currentTime := time.Now() endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location()) fmt.Println(endTime) fmt.Println(endTime.Format("2006/01/02 15:04:05")) 03: 获取1分钟之前的时间 m, _ := time.ParseDuration("-1m") result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format("2006/01/02 15:04:05")) 04: 获取1小时之前的时间 m, _ := time.ParseDuration("-1h") result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format("2006/01/02 15:04:05")) 05: 获取1分钟之后的时间 m, _ := time.ParseDuration("1m") result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format("2006/01/02 15:04:05")) 06: 获取1小时之后的时间 m, _ := time.ParseDuration("1h") result := currentTime.Add(m) fmt.Println(result) fmt.Println(result.Format("2006/01/02 15:04:05")) 07 :计算两个时间戳 afterTime, _ := time.ParseDuration("1h") result := currentTime.Add(afterTime) beforeTime, _ := time.ParseDuration("-1h") result2 := currentTime.Add(beforeTime) m := result.Sub(result2) fmt.Printf("%v 分钟 \n", m.Minutes()) h := result.Sub(result2) fmt.Printf("%v小时 \n", h.Hours()) d := result.Sub(result2) fmt.Printf("%v 天\n", d.Hours()/24) 08: 判断一个时间是否在一个时间之后 stringTime, _ := time.Parse("2006-01-02 15:04:05", "2019-12-12 12:00:00") beforeOrAfter := stringTime.After(time.Now()) if true == beforeOrAfter { fmt.Println("2019-12-12 12:00:00在当前时间之后!") } else { fmt.Println("2019-12-12 12:00:00在当前时间之前!") } 09: 判断一个时间相比另外一个时间过去了多久 startTime := time.Now() time.Sleep(time.Second * 5) fmt.Println("离现在过去了:", time.Since(startTime))
2.命令行解析
package main import ( "flag" "fmt" "os" ) //先编译 go build -o args.exe args_test.go //执行 args.exe -name .. func main() { //第一种 //获取命令行参数 //fmt.Print(os.Args) for i,v := range os.Args{ fmt.Print(i,v) } //第二种 //自定义命令行参数 //定义参数 //String代表获取的参数类型为字符串,参数的名字为-name,值默认为空,usage为提示 namePtr := flag.String("name", "", "姓名") agePtr := flag.Int("age",18,"年龄") rmbPtr := flag.Float64("rmb",10000,"资产") alivePtr := flag.Bool("alive",true,"是否健在") //解析获取参数,丢入参数的指针中 flag.Parse() fmt.Print(*namePtr,*agePtr,*rmbPtr,*alivePtr) //第三种 //var name *string 这里在栈里面占了名字,但是没有分配内存空间,所以没有地址 // //flag.StringVar(name,"name", "", "姓名") var name string//这里是有地址的 var age int var rmb float64 var alive bool flag.StringVar(&name,"name", "", "姓名") flag.IntVar(&age,"age",18,"年龄") flag.Float64Var(&rmb,"rmb",10000,"资产") flag.BoolVar(&alive,"alive",true,"是否健在") flag.Parse() fmt.Print(name,age,rmb,alive) }
3.time库使用
package main import ( "time" "fmt" ) func main(){ //本地时间 nowTime := time.Now() //年月日 year := nowTime.Year() fmt.Printf("%s",year) month := nowTime.Month() fmt.Printf("%s",month) y,m,d := nowTime.Date() fmt.Printf("%d:%d:%d",y,m,d) //周月年中的第几天 day := nowTime.Day() fmt.Printf("%d",day) yearDay := nowTime.YearDay() fmt.Printf("%d",yearDay) weekDay := nowTime.Weekday() fmt.Printf("%d",weekDay) //时分秒 fmt.Printf("%s",nowTime.Hour()) fmt.Printf("%s",nowTime.Minute()) fmt.Printf("%s",nowTime.Second()) fmt.Printf("%s",nowTime.Nanosecond()) //创建时间 date := time.Date(2019,time.September,8,15,0,0,0,time.Now().Location()) fmt.Printf("%s",date) //Add方法和Sub方法是相反的 //获取t0和t1的时间距离d是使用Sub //将t0加d获取t1就是使用Add方法 now := time.Now() //一天之前 duration,_ := time.ParseDuration("-24h0m0s") fmt.Printf("%s",now.Add(duration)) //一周之前 fmt.Printf("%s",now.Add(duration * 7)) //一月之前 fmt.Printf("%s",now.Add(duration * 30)) //计算时间差 fmt.Printf("%s",now.Sub(now.Add(duration))) }
4.文件读取
package main import ( "bufio" "fmt" "io" "io/ioutil" "os" ) func main00(){ //打开文件与1关闭文件 file,err :=os.Open("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt") if err == nil { fmt.Printf("文件打开成功") fmt.Println(file) } else{ fmt.Printf("文件打开失败,err:",err) return } defer func(){ file.Close() fmt.Printf("关闭文件") }() // } func main01(){ //以只读方式打开一个文件,创建其带缓冲的读取器,逐行读取到末尾 //4=readable,2=writeable,1=executeable,6=4+2 file,err :=os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt",os.O_RDONLY,0666) //判断读入是否成功 if err == nil { fmt.Printf("文件打开成功") //打印内容 fmt.Println(file) } else{ fmt.Printf("文件打开失败,err:",err) return } //延迟关闭文件:在函数return前执行的程序 defer func(){ file.Close() fmt.Printf("关闭文件") }() //创建文件的读取器 Reader := bufio.NewReader(file) for{ //一次读取一行 data,err := Reader.ReadString('\n') if err == nil{ fmt.Println(data) }else{ //到达文件结尾,跳出循环 if err == io.EOF{ fmt.Println("已经文件结尾") break }else{ //读取异常,打印异常并结束 fmt.Println("读取失败,err:",err) return } } } } func main03(){ //使用ioutil包对文件进行快捷读取 //读取文件的全部数据,返回原始数据[]byte类型的原始数据 data,err := ioutil.ReadFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt") if err == nil{ Content_data := string(data) fmt.Println(Content_data) }else{ fmt.Println("读取失败") } //内部执行defer函数 }
5.文件写入
func mian04(){ //以【创写追加】或【创写覆盖】方式打开一个文件,缓冲写出几行数据,倒干缓冲区 //打开文件,模式:不存在就创建+只写+追加,生成的文件的权限666 file,err :=os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt",os.O_CREATE|os.O_WRONLY|os.O_APPEND,0666) //判断读入是否成功 if err != nil { fmt.Printf("文件打开失败,err:",err) return } //延迟关闭文件:在函数return前执行的程序 defer func(){ file.Close() fmt.Printf("关闭文件") }() //分批写入数据 writer := bufio.NewWriter(file) writer.WriteString("hello") writer.WriteString("2019") writer.WriteString("。。。。") //写入一个字符 writer.WriteRune('你') writer.WriteRune('好') //写一位数据 writer.WriteByte(123) //写一个字节数据,范围:0-255 writer.Write([]byte{123,222,21}) //把缓冲区清空,立即将最后的数据写入文件 writer.Flush() } func main05(){ //反引号代表保留原始排版的字符串 data := `测试文档、1、2、3、4、5。` fmt.Printf("data type=%T,value=%v\n",data,data) //将数据字符串转换为原始字节切片 dataBytes := []byte(data) fmt.Printf("data type=%T,value=%v\n",dataBytes,dataBytes) //向指定文件写入上面的字节数据 err := ioutil.WriteFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt",dataBytes,0666) if err != nil { fmt.Println("写出错误") }else{ fmt.Println("写出成功") } } func main06(){ //使用os包状态检测结合os.IsNotExist(err)判断文件是否存在 //获取指定文件的信息 fileInfo,err := os.Stat("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt") if err != nil { fmt.Println("err=",err) //校验错误是否为【文件不存在错误】 if os.IsNotExist(err){ fmt.Println("文件不存在!") } return }else{ fmt.Println("文件存在!") fmt.Println(fileInfo) } }
6.文件拷贝
//使用ioutil包做一个傻瓜式拷贝 //使用io.Copy进行文件拷贝 //使用缓冲1K的缓冲区配合缓冲读写器进行图片拷贝 func main07(){ //使用ioutil包做一个傻瓜式拷贝 data,_:= ioutil.ReadFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt") err := ioutil.WriteFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test1.txt",data,0666) if err != nil{ fmt.Println("拷贝失败",err) }else{ fmt.Println("拷贝成功") } fmt.Println("执行完成") } func main08(){ //使用io.Copy进行文件拷贝 //打开拷贝源文件,模式为只读模式 srcFile,err := os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt",os.O_RDONLY,0666) //打开目标文件,模式为创建|写入 dstFile,err := os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test1.txt",os.O_WRONLY |os.O_CREATE,0666) //执行源文件到目标文件的拷贝,writen为拷贝字节数 writen,err := io.Copy(dstFile,srcFile) if err == nil { fmt.Println("拷贝成功,字节数=",writen) }else{ fmt.Println("拷贝失败,err=",err) } } func main09(){ //使用缓冲1K的缓冲区配合缓冲读写器进行图片拷贝 //打开源文件 srcFile,_ := os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test.txt",os.O_RDONLY,0666) //打开目标文件 dstFile,_ := os.OpenFile("C:/Users/Administrator/go/src/awesomeProject/demo/test/test1.txt",os.O_WRONLY |os.O_CREATE,0666) defer func(){ srcFile.Close() dstFile.Close() fmt.Println("文件全部关闭!") }() //创建源文件的缓冲读取器 reder := bufio.NewReader(srcFile) //创建目标文件的缓冲写出器 writer := bufio.NewWriter(dstFile) //创建缓冲区 buffer := make([]byte,1024) //将数据存入,直到io.EOF for { //循环的读取数据到缓冲区,然后把缓冲区的数据写入到目标文件 _,err :=reder.Read(buffer) if err !=nil{ if err == io.EOF{ fmt.Println("源文件读取完毕!") break }else{ fmt.Println("读取文件发生错误,err=",err) } }else{ _,err := writer.Write(buffer) if err !=nil { fmt.Println("写出错误,err=",err) return } } } }
7.序列化与反序列化
package main import ( "encoding/json" "fmt" ) //JSON的序列化 //将结构体构成数据,并转JSON //将map[string]interface{}构成数据,并转JSON //使用map切片构成数据,并转JSON //json.cn //将结构体构成数据,并转JSON //使用Man 结构体构成数据,并转为json type Man struct{ Name string Age int Hobby []string Sex bool } func maina1(){ person := Man{"liyi",20,[]string{"唱歌","跳舞"},true} bytes,err := json.Marshal(person) if err != nil{ fmt.Println("序列化失败,err=",err) return }else{ fmt.Println("序列化成功,err=",err) fmt.Println(string(bytes)) } } //将map[string]interface{}构成数据,并转JSON //这里interface{}代表任意数据类型 func maina2(){ dataMap := make(map[string]interface{}) dataMap["name"] ="liyi" dataMap["age"] = 20 dataMap["hobby"] = []string{"唱歌","跳舞"} dataMap["sex"] = true bytes,err := json.Marshal(dataMap) if err != nil{ fmt.Println("序列化失败,err=",err) return }else{ fmt.Println("序列化成功,err=",err) fmt.Println(string(bytes)) } } //使用map切片构成数据,并转JSON func maina3(){ dataMap1 := make(map[string]interface{}) dataMap1["name"] ="liyi" dataMap1["age"] = 20 dataMap1["hobby"] = []string{"唱歌","跳舞"} dataMap1["sex"] = true dataMap2 := make(map[string]interface{}) dataMap2["name"] ="linging" dataMap1["age"] = 21 dataMap1["hobby"] = []string{"打炮"} dataMap1["sex"] = true dataMap3 := make(map[string]interface{}) dataMap3["name"] ="yiyi" dataMap3["age"] = 18 dataMap3["hobby"] = []string{"学习"} dataMap3["sex"] = true dataSlice := make([]map[string]interface{}, 0) dataSlice = append(dataSlice,dataMap1,dataMap2,dataMap3) bytes,err := json.Marshal(dataSlice) if err != nil{ fmt.Println("序列化失败,err=",err) return }else{ fmt.Println("序列化成功") fmt.Println(string(bytes)) } } //JSON的反序列化 //将json数据转为map //将json数据转为结构体 //将json数据转换为map切片 //将json数据转为结构体切片 //将json数据转为map func maina4(){ //json数据 jsonStr := `{"Name":"liyi","Age":18,"Hobby":["抽烟","喝酒"],"sex":true}` //将json数据转为字节数据 jsonbytes := []byte(jsonStr) dataMap := make(map[string]interface{}) err := json.Unmarshal(jsonbytes,&dataMap) if err != nil { fmt.Println("反序列化失败,err=",err) } fmt.Println(dataMap) } //将json数据转为结构体 func maina5(){ type Man struct{ Name string Age int Hobby []string Sex bool } //json数据 jsonStr := `{"Name":"liyi","Age":18,"Hobby":["抽烟","喝酒"],"sex":true}` //将json数据转为字节数据 jsonbytes := []byte(jsonStr) //创建一个结构体 Man1 := new(Man) err := json.Unmarshal(jsonbytes,&Man1) if err != nil { fmt.Println("反序列化失败,err=",err) } fmt.Println(*Man1) } //将json数据转换为map切片 func maina6(){ jsonStr := `[{"age":21,"hobby":["打炮"],"name":"liyi","sex":true},{"name":"linging"},{"age":18,"hobby":["学习"],"name":"yiyi","sex":true}]` jsonBytes := []byte(jsonStr) dataSlice := make([]map[string]interface{},0) err := json.Unmarshal(jsonBytes,&dataSlice) if err != nil { fmt.Println("反序列化失败,err=",err) } fmt.Println(dataSlice) } //将json数据转为结构体切片 func maina7() { type Man struct { Name string Age int Hobby []string Sex bool } jsonStr := `[{"age":21,"hobby":["打炮"],"name":"liyi","sex":true},{"name":"linging"},{"age":18,"hobby":["学习"],"name":"yiyi","sex":true}]` jsonBytes := []byte(jsonStr) Mans := make([]Man, 0) err := json.Unmarshal(jsonBytes, &Mans) if err != nil { fmt.Println("反序列化失败,err=", err) } fmt.Println(Mans) }
8.Json编码与解码
//编码:go数据--》json文件 //解码:json文件--》go数据 //使用json包编码 //注意:解码json数据,需要对应的数据类型的数据来接收!!!
//将map类型数据编码为json文件 func mainb0() { //go数据:map类型 dataMap1 := make(map[string]interface{}) dataMap1["name"] = "liyi" dataMap1["age"] = 20 dataMap1["hobby"] = []string{"唱歌", "跳舞"} dataMap1["sex"] = true //打开文件 dstFile, _ := os.OpenFile("C:/test/test1.json", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) defer dstFile.Close() //创建编码器 encoder := json.NewEncoder(dstFile) //编码 err := encoder.Encode(dataMap1) if err != nil { fmt.Println("编码失败,err=", err) return } fmt.Println("编码成功") } //将结构体切片编码转为json文件 func mainb1(){ type Man struct { Name string Age int Hobby []string Sex bool } person1 := Man{"liyi",20,[]string{"唱歌","跳舞"},true} person2 := Man{"yiyi",20,[]string{"唱歌","跳舞"},true} person3 := Man{"meng",20,[]string{"唱歌","跳舞"},true} people := make([]Man,0) people = append(people,person1,person2,person3) dstFile,_ := os.OpenFile("C:/test/test1.json",os.O_CREATE | os.O_WRONLY | os.O_APPEND,0666) defer dstFile.Close() encoder := json.NewEncoder(dstFile) err := encoder.Encode(people) if err != nil { fmt.Println("编码失败,err=", err) return } fmt.Println("编码成功") } //解码json文件为map func mainc1(){ //打开json文件 srcFile,_ := os.Open("C:/test/test1.json") defer srcFile.Close() //创建接收数据的map类型数据 datamap := make(map[string]interface{}) //创建解码器 decoder := json.NewDecoder(srcFile) //解码 err := decoder.Decode(&datamap) if err != nil{ fmt.Println("解码失败,err=",err) return } fmt.Println("解码成功",datamap) } //解码json文件为结构体 func mainc2(){ type Man struct { Name string Age int Hobby []string Sex bool } //打开json文件 srcFile,_ := os.Open("C:/test/test1.json") defer srcFile.Close() //创建接收数据的结构体数据 datastruct := make([]Man,0) decoder := json.NewDecoder(srcFile) //解码 err := decoder.Decode(&datastruct) if err != nil{ fmt.Println("解码失败,err=",err) return } fmt.Println("解码成功",datastruct) }
Go-面向对象
Go-并发
Go-数据库
Go-web框架