go 快速入门
1 go mod包管理工具
Tip
将github上的一个仓库作为你go项目的一个包来使用
在 go get 的时候如果不手动指定版本信息,会自动拉取最新的版本的包
如果想要拉取指定版本可以通过 go get github.com/pkg/errors@v0.9.0 的方式
@版本号例如@v0.9.0@分支名例如@master@committag 例如@6cff360233dc4457f1536e4f3df4e4e740fd3410
// indirect 表示 这个包我们没有在代码中直接import 使用它, 大概是间接依赖的包, 比如 import A, 然后A里有import B, B就是我们间接依赖的包
当你在main.go 里使用了我们前面go get的包errors, 再去看下 go.mod 会看到提示说 should be direct
2 编译运行
查看编译过程
go mod init test
go build -n
# import config
packagefile fmt=...
# 一个go程序会将runtime 编译进去.
packagefile runtime=...
# 编译
/usr/local/go/pkg/tool/linux_amd64/compile -o
# 要link 的文件清单
cat >$WORK/b001/importcfg.link ...
# link 操作
/usr/local/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/a.out
/usr/local/go/pkg/tool/linux_amd64/buildid -w $WORK/b001/exe/a.out
# 重命名
mv $WORK/b001/exe/a.out test3 基本数据类型
// 每当遇到const, 就会重置为0
const c1 = iota // 0
const (
// const() 中每增加一行声明就会将iota计数 +1
a = "hello" // hello
b // hello
c = 9
d // 9 使用与它最近的表达式 这里是上面的 9
e // 9
a1 = iota // 5 前面a 那里是0
a2 //6
_ //7
a4 //8
b1 = iota //9
b2 // 10
)
const (
d1 = iota * 2 // 0
d2 //2
d3 = iota * 3 // 6
d4 //9 使用最近的 表达式 iota*3
)
const (
e1 = 1 << iota //1
e2 //2 左移 iota=1 位
e3 //4 左移 iota=2 位
)
const pi=3.14
func main() {
// # 常量是无法做 取址操作的,会报错
println(&pi)
}
Tip
const申明的常量,是在编译期间就已经确定的固定值,你无法修改,所以你取址操作无意义
4 空结构体struct
Important
不占用内存, 经常用, 用来节约内存
package main
import (
"fmt"
"unsafe"
)
func main() {
a := struct{}{}
b := struct{}{}
fmt.Println(unsafe.Sizeof(a), unsafe.Sizeof(b)) //0
// 相同
fmt.Printf("%p,%p\n", &a, &b)
d := uintptr(unsafe.Pointer(&a))
fmt.Println(d)
cat := Cat{
Name: "abc",
Ag: struct{}{},
Age: 11,
Weight: 110,
}
// 我们发现 结果是32 , 在结构体里成员类型是空 struct{} ,也是不占用空间的
fmt.Println(unsafe.Sizeof(cat))
// 但是 和上面的 a, b 的 空结构体地址不一样.
// &cat.Ag, &cat.Age 地址一样
fmt.Printf("%p,%p,%p,%p\n", &cat.Name, &cat.Ag, &cat.Age, &cat.Weight)
dog := Dog{
Ag: struct{}{},
Name: "abc",
Age: 11,
Weight: 110,
}
fmt.Println(unsafe.Sizeof(dog)) // 32 不占用空间
// &dog.Ag, &dog.Name 地址一样
fmt.Printf("%p,%p,%p,%p\n", &dog.Ag, &dog.Name, &dog.Age, &dog.Weight)
// 放在结构体最后
h1 := struct {
b byte
s struct{}
}{}
fmt.Printf("%p,%p\n", &h1.b, &h1.s)
// 2 个字节, 也就是说填充了一个字节
// 试着 将 b 弄成 int16 int32 int64 看看
fmt.Println(unsafe.Sizeof(h1))
}
type Cat struct {
Name string //16 byte
Ag struct{}
Age int64 // 8
Weight int64 // 8
}
type Dog struct {
Ag struct{}
Name string //16 byte
Age int64 // 8
Weight int64 // 8
}底层原理
5 nil
Tip
nil 是一个变量
源码中,请看看注释