Go学习记录

Go Module

基本现在安装的go版本都是1.8之后的了,go1.8之前第三方依赖目录再GOPATH,1.8之后go引入了module管理第三方依赖,因此不需要GOPATH

go 常用命令

1
2
3
4
5
go mod init   #初始化模块,例如 go mod init github.com/wjp2013/hello
go build, go test #和其它构建命令会自动为 go.mod 添加新的依赖
go get #改依赖关系的所需版本(或添加新的依赖关系)
go list -m all #列出当前模块及其所有依赖项
go mod tidy #拉取缺少的模块,移除不用的模块

不常用命令

1
2
3
4
5
6
go mod download   #下载依赖包到本地 cache
go mod edit #编辑 go.mod 文件,选项有 -json、-require 和 -exclude,可以使用帮助 go help mod edit
go mod graph #打印模块依赖图
go mod vendor #将依赖复制到 vendor 目录
go mod verify #验证依赖是否正确
go mod why #解释为什么需要依赖

变量

在包级别声明的变量会在main入口函数执行前完成初始化,局部变量将在声明语句被执行到的时候完成初始化。

var 变量名字 类型 = 表达式

1
2
3
4
var str string
var num int = 0
var i, j, k int // int, int, int
var b, f, s = true, 2.3, "four" // bool, float64, string

简短变量

用于声明和初始化局部变量,变量的类型根据表达式来自动推导。

var形式的声明语句往往是用于需要显式指定变量类型的地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

变量中必须至少声明一个新的变量

名字 := 表达式

1
2
3
4
5
6
freq := rand.Float64() * 3.0
t := 0.0
i, j := 0, 1 //初始化一组变量

in, err := os.Open(infile) //初始化in和err
out, err := os.Create(outfile) //初始化out,赋值err

注意区分i, j = j, i // 交换 i 和 j 的值

指针

指针的值存放的是地址,该地址指向了另一个变量的值,如下图指针p存放的是地址,该地址为变量x存放的值。通过间接运算符*获取指针指向的值,取址运算符&能去的该地址的值

image-20220317165544043

1
2
3
4
5
6
7
8
x := 12
p := &x // 指针p,p的值为x的地址
fmt.Println(p) // 0xc000102090
fmt.Println(*p) // 12
fmt.Println(&p) // 0xc00012c028

*p = 2 // equivalent to x = 2
fmt.Println(x) // "2"

野指针

野指针是一种指向内存位置是不可知的指针,一般是由于指针变量在声明时没有初始化所导致的。

1
2
3
4
5
6
7
8
9
10
var p *int // 指针声明未初始化,野指针
fmt.Printf("%p\n", ptr) // 0x0

// *p = 10 panic 无效的内存地址或 nil 指针解引用 Pointer Dereference,野指针不能进行 *p 取值
fmt.Println(ptr) // nil

var a int = 10
p = &a // 可以重新指向变量 a 的地址
*p = 2 // 即可修改变量a 内存地址的值
fmt.Println(a) // 2

悬空指针

悬空指针是指它最初指向的内存空间已经被释放掉了,在 Go 语言中,如果函数内变量的地址作为函数返回值,编译器就会判断出该变量在函数调用完成后还需要被引用,因此不在栈中为其分配存储空间,而是在堆中为其分配存储空间,这样的变量在函数调用完成后其占用的存储空间不会被立刻释放,也就避免出现悬空指针这种情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Command struct {
Name string // 指令名称
Var *int // 指令绑定的变量
Comment string // 指令的注释
}

func newCommand(name string, varref *int, comment string) *Command {
return &Command{
Name: name,
Var: varref,
Comment: comment,
}
}

cmd = newCommand(
"version",
&version,
"show version",
)