从这小节开始,就变得尤为重要,希望小伙伴们打起精神
包管理工具(go module)
- 使用go module来管理0包之间的依赖关系
- 和Java类似,类似于文件夹。当我们需要使用某个包时,导入某个包即可
- 导包时,必须从GOPATH最初的包路径开始
// 查看环境变量
PS D:\gowork\goProiect\Go01Test> go env
set GO111MODULE=on //模块化
set GOARCH=amd64
set GOPROXY=https://proxy.golang.com.cn,direct
set GOROOT=C:\Program Files\Go
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set CC=gcc
set CXX=g++ ......
相关命令
- go mod init <项目名称>
- go mod download [path@version]
- go mod tidy 处理依赖关系
小案例
- 根目录下新建项目Go01Test
- 执行go mod init goproject/go01test命令,自动生成main.go文件(主文件入口)
- 在该目录下创建service文件夹,并创建user_service.go测试文件
// \Go01Test\service/use_service.go
package service
import "fmt"
func TestUserService() {
fmt.Println("test user service !")
}
- 此时将目录切至service下,执行:
PS D:\gowork\goProiect\Go01Test> cd .\service\
PS D:\gowork\goProiect\Go01Test\service> go build//编译至缓存中,便于其他包搜索
- 将service包导入主文件:
package main
import (
"fmt"
"goproject/go01test/service" // 导包
)
func main() {
fmt.Println("hello world !")
service.TestUserService()
}
// 执行结果:
return:
[Running] go run "d:\goProiect\Go01Test\main.go"
hello world !
test user service !
[Done] exited with code=0 in 1.198 seconds
标准库
1.OS(与平台无关的编程接口)
- 创建文件相关操作
// 仅展示相关伪代码
import (
"fmt"
"os"
)
// 1.创建文件
func creatFile() {
f, err := os.Create("a.txt")
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("f.Name(): %v\n", f.Name())
}
}
func main() {
creatFile() // 再次创建会覆盖原文件
}
//源码:
func Create(name string) (*File, error) {
return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}
// 2.创建目录
func makeDir() {
err := os.Mkdir("test", os.ModePerm) // 创建权限
if err != nil {
fmt.Printf("err: %v\n", err)
}
// 创建级联目录
err2 := os.MkdirAll("a/b", os.ModePerm)
if err2 != nil {
fmt.Printf("err2: %v\n", err2)
}
}
// 3.删除目录
func removeDir() {
err := os.RemoveAll("test")
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
// 4.获取目录
func getContent() {
dir, err := os.Getwd()
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("dir: %v\n", dir)
}
}
- File读操作
func readFile() {
f, err := os.Open("a.txt") // 返回文件句柄(对错误不做处理)
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("f.Name(): %v\n", f.Name())
f.Close() // 一定要及时关闭
}
}
func openFileH() {
// 打开文件,若不存在立即创建
f, err := os.OpenFile("b.txt", os.O_RDWR|os.O_CREATE, 755) //最高权限(读写,执行)
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("f.Name(): %v\n", f.Name())
f.Close()
}
}
//读取文件
func readFiles() {
// 循环读写(未知内容大小)
f, _ := os.Open("a.txt")
for {
buff := make([]byte, 5) // 缓冲区
n, err := f.Read(buff)
if err == io.EOF { // 等于文件末尾,执行退出
break
}
fmt.Printf("n: %v\n", n)
fmt.Printf("string(buff): %v\n", string(buff))
}
f.Close()
}
原文件:hello everyone !
return:
n: 5
string(buff): hello
n: 5
string(buff): ever
n: 5
string(buff): yone
n: 1
string(buff): !
- File写操作
func writeFile() {
f, _ := os.OpenFile("a.txt", os.O_RDWR|os.O_APPEND, 0755) // 打开写权限
f.Write([]byte("end"))
f.Close()
}
2.bufio(缓冲区)
- bufio实现了有缓冲区的I/O
package main
import (
"bufio"
"fmt"
"strings"
)
func test01() {
// 读取字符串
r := strings.NewReader("hello world")
r2 := bufio.NewReader(r)
s, _ := r2.ReadString('\n')
fmt.Printf("s: %v\n", s)
}
func test02() {
// 读取文件
r, _ := os.Open("a.txt")
r2 := bufio.NewReader(r)
s, _ := r2.ReadString('\n')
fmt.Printf("s: %v\n", s)
}
func test03() {
// 写文件
f, _ := os.OpenFile("a.txt", os.O_RDWR, 0777)
// File内部实现了Reader和Writer
// 关闭文件
defer f.Close()
w := bufio.NewWriter(f)
w.WriteString("hello world") // 具有缓冲功能,更高效传递文件
w.Flush() // 刷新缓冲区
}
3.sort(排序相关)
- 提供切片与自定义数据排序相关函数
package main
import (
"fmt"
"sort"
)
func test01() {
i := []int{3, 2, 4, 5, 1}
sort.Ints(i)
fmt.Printf("i: %v\n", i)
}
func test02() {
i := []float64{3.1, 2.1, 4.1, 5.1, 1.1}
sort.Float64s(i)
fmt.Printf("i: %v\n", i)
}
func test03() {
// 字符串排序,先比较高位,相同的再比较低位
ss := sort.StringSlice{
"111",
"222",
"11",
"2222",
"1",
}
fmt.Printf("ss: %v\n", ss)
sort.Strings(ss)
fmt.Printf("ss: %v\n", ss)
}
func test04() {
ss2 := sort.StringSlice{
"c",
"e",
"a",
"z",
"h",
}
sort.Strings(ss2)
fmt.Printf("ss2: %v\n", ss2)
}
return:
i: [1 2 3 4 5]
i: [1.1 2.1 3.1 4.1 5.1]
ss: [111 222 11 2222 1]
ss: [1 11 111 222 2222]
ss2: [a c e h z]
4.web相关
4.1时间
- 基础相关:
import (
"fmt"
"time"
)
func test01() {
t := time.Now() // 获取当前时间
fmt.Printf("t: %v\n", t)
fmt.Printf("t.Year(): %v\n", t.Year())
fmt.Printf("t.Month(): %v\n", t.Month())
fmt.Printf("t.Day(): %v\n", t.Day())
fmt.Println(t.Date())
fmt.Printf("t.Minute(): %v\n", t.Minute())
fmt.Printf("t.Second(): %v\n", t.Second())
}
return:
t: 2022-12-03 16:47:41.6122579 +0800 CST m=+0.002319801
t.Year(): 2022
t.Month(): December
t.Day(): 3
2022 December 3
t.Minute(): 47
t.Second(): 41
- 时间戳
- 时间戳是自1970.1.1日起至当前时间的总毫秒数。
- 开发中涉及到有效期的实现,比如:cookie的有效期,登录验证时长等
- 获取当前时间戳:
func test02() {
t := time.Now()
fmt.Printf("t.Unix.type: %T\nt.Unix.value: %v\n", t.Unix(), t.Unix())
}
return:
t.Unix.type: int64
t.Unix.value: 1670057879
- 转换为普通时间格式:
func test03() {
i := time.Now().Unix() // 拿到时间戳
t := time.Unix(i, 0) // 将其转化为时间格式
fmt.Printf("t: %v\n", t)
}
4.2 json
- 即对前端发开的数据进行解析;对后端传递的数据进行封装
- marshal:n.元帅,司仪,典礼;vt.收集,组织,控制,维持秩序
// 1.结构体转json(向前端发送)
import (
"encoding/json"
"fmt"
)
type Man struct {
Name string
Age int
Tel string
}
func main() {
m := Man{
Name: "c1",
Age: 22,
Tel: "101",
}
b, _ := json.Marshal(m) // b是字节切片
fmt.Printf("b: %v\n", string(b)) // 将字节切片强转为string类型的数据
}
return:
b: {"Name":"c1","Age":22,"Tel":"101"}
// 2.json转结构体(后端接收)
func test01() {
b := []byte(`{"Name":"c1","Age":22,"Tel":"101"}`)
var m Man
json.Unmarshal(b, &m)
fmt.Printf("m: %v\n", m) //指针类型(取地址)
}
return:
m: {c1 22 101}