Skip to content

Commit ff0f61d

Browse files
committed
更新go运行时文档以及其他小部分校正
1 parent 8017dda commit ff0f61d

28 files changed

+741
-501
lines changed

01-基础语法/07-类型转换与别名.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,37 @@ type Student = Person
154154
func (p *Student) Study() {
155155
fmt.Println("study...")
156156
}
157-
```
157+
```
158+
159+
### 三 Go的类型系统补充
160+
161+
### 3.1 命名类型和未命名类型
162+
163+
- 命名类型:Named Type。类型通过标识符、自定义类型表示
164+
- 未命名类型:Unamed Type。也称为类型字面量(Type Literal),由预声明类型、关键字、操作符等组合而成,如array、slice、channel、pointer、function、未使用type定义的struct、未使用type定义的interface。
165+
166+
示例:
167+
```go
168+
// 命名类型,其类型是 Person
169+
type Person struct {
170+
name string
171+
}
172+
// 未命名类型,其类型是 struct { name string }
173+
p := struct {
174+
name string
175+
}
176+
```
177+
178+
### 3.2 底层类型
179+
180+
所有类型都有一个底层类型 underlying type,其规则如下:
181+
- 预声明类型(Pre-declared types)和类型字面量(type literals)的底层类型是他们自身
182+
- 自定义类型`type newtype oldtype`中newtype的底层类型是逐层递归向下查找的,直到找到oldtype的预声明类型或字面量类型
183+
184+
### 3.3 Go中的类型相同
185+
186+
Go中类型相同的规范:
187+
- 命名类型的数据类型相同:声明语句必须完全相同
188+
- 未命名类型数据类型相同:类型声明字面量结构相同,且内部元素的类型相同
189+
- 命名类型与未命名类型永远不同
190+
- 通过类型别名语句声明的两个类型相同。类型别名语法:`type T1 = T2`

01-基础语法/12-接口类型-2-断言与多态.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
接口是编程的规范,他也可以作为函数的参数,以让函数更具备适用性。在下列示例中,有三个接口动物接口、飞翔接口、游泳接口,两个实现类鸟类与鱼类:
44
- 鸟类:实现了动物接口,飞翔接口
55
- 鱼类:实现了动物接口,游泳接口
6-
-
6+
77
```go
88
package main
99

@@ -92,6 +92,8 @@ func Display(a Animal) {
9292

9393
## 二 接口类型转换
9494

95+
在接口定义时,其类型已经确定,因为接口的本质是方法签名的集合,如果两个接口的方法签名结合相同(顺序可以不同),则这2个接口之间不需要强制类型转换就可以相互赋值,因为go编译器在校验接口是否能赋值时,比较的是二者的方法集。
96+
9597
在上一节中,函数Display接收的是Animal接口类型,在断言后转换为了别的类型:*Bird(实现类指针类型):
9698
```go
9799
func Display(a Animal) {

03-工程管理/00-Go编程哲学.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## 一 Go语言的设计思想
2+
3+
- 少即是多:
4+
- 很少的语法特性
5+
- 满足语言特性的正交性:多个组成因子中,一个发生变化,不会影响其他因子变化。Go中的goroutine、interface、类型系统的组合能够极大增强Go的表现力
6+
- 把一种事情做到极致,而不是提供多个选择。如 for 循环一个关键字可以替代 for、while、do while三种C语言的场景
7+
- 组合优于继承:世界由万物组合而成,而不是万物皆对象。继承关系只是世界表象中一个很小的子集,组合才是世界组成的根本。
8+
- 非侵入式接口:Go的接口采用了一种Duck模型,具体类型不需要显式的声明自己实现了某个接口,只要方法集是接口方法集的超集即可。接口类型的是否实现判断交给了编译器处理,该方式让接口和实现者之间实现了解耦。
9+
10+
## 二 Go语言中的设计争议
11+
12+
- 包管理:饱受诟病!!但是在go1.13中得到大幅改善(1.11中即可开启新版包管理方式)
13+
- 错误处理:Go的错误处理简单粗暴,但是绝对不优雅!
14+
- 泛型支持:Go没有泛型支持,笔者认为无法容忍!
15+

03-工程管理/01-包.md

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 一 包的使用
22

3-
#### 1.1 package与import
3+
### 1.1 package与import
44

55
在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,比如 main.go 中,需要使用"fmt"包中的Println()函数:
66
```go
@@ -28,7 +28,9 @@ import (
2828
)
2929
```
3030

31-
#### 1.2 GOPATH
31+
推荐:一般包名为全小写格式,且使用一个简短的命名。
32+
33+
### 1.2 GOPATH
3234

3335
GOPATH与GROOT:
3436
```
@@ -48,15 +50,15 @@ GOPATH允许多个目录,多个目录的时候Windows是分号,Linux系统
4850
- bin:编译后生成的可执行文件,可以加入$PATH中
4951
>注意:一般建议package的名称和目录名保持一致
5052
51-
#### 1.3 包中的函数调用方式
53+
### 1.3 包中的函数调用方式
5254

5355
函数调用的方式:
5456
- 同包下:直接调用即可
5557
- 不同包下:包名.函数名
5658

5759
注意:Go中,大写字母开头的变量是可导出的,也就是其它包可以读取的,是公有变量;小写字母开头的就是不可导出的,是私有变量。
5860

59-
#### 1.4 init函数 与 _
61+
### 1.4 init函数 与 _
6062

6163
init()函数在包加载时就会默认最先调用,用来对包中的一些属性进行初始化操作:
6264
```go
@@ -76,7 +78,7 @@ import _ "package1"
7678

7779
一个go包可以拥有读个init函数,会按照包中不同文件名顺序、同文件名中init函数前后顺序依次调用。
7880

79-
#### 1.5 点操作
81+
### 1.5 点操作
8082

8183
点语法在使用包调用函数时,可以省略包名:
8284
```go
@@ -87,16 +89,57 @@ Println("无需包名即可调用...")
8789

8890
不推荐该使用方式。
8991

90-
#### 1.6 包别名
92+
### 1.6 包别名
9193
```go
9294
import p1 "package1" // 此时包 package1 可以在代码中使用 p1 代替
9395
```
9496

95-
## 包的管理
97+
## 下载第三方包
9698

9799
go有很多优秀的第三方包,可以使用 `go get 包地址`来下载,下载的包会默认安装在Gopath目录中的src文件夹中。
98100

99-
Gopath支持多个目录,`go get`默认都会将包下载到配置的第一个Gopath中。
101+
Gopath支持多个目录,`go get`默认都会将包下载到配置的第一个gopath中。
102+
103+
## 三 包的加载
104+
105+
在程序执行前,Go引导程序会先对整个程序的包进行初始化:
106+
- 包初始化程序从 main 函数引用的包开始,逐级查找包的引用,直到找到没有引用其他包的包,最终生成一个包引用的有向无环图
107+
- Go 编译器会将有向无环图转换为一棵树,然后从树的叶子节点开始逐层向上对包进行初始化
108+
- 单个包的初始化中,先初始化常量,然后是全局变量,最后执行包的init 函数(如果有)
109+
110+
111+
## 四 包的管理(已过时,推荐Go1.11后的go mod)
112+
113+
### 4.1 vendor
114+
115+
vendor机制是指在保重加入了一个额外的vendor目录,将依赖的外部包复制到vendor目录下(nodejs???),编译器在查找外部依赖包时,查找顺序是:
116+
- 优先在vendor目录下查找
117+
- 如果当前包目录下没有vendor目录,则沿着当前包向上级目录查找vendor目录,直到$GOPATH/src下的vendor目录
118+
- 如果还没有vendor,则查找GOPATH下的依赖包
119+
- 最后查找GOROOT下的依赖包
120+
121+
Go1.5中的版本机制,需要手动设置 GOl 5VENDOREXPERIMENT=1后编译器才能启用,Go1.6后默认支持开启vendor目录查找。
122+
123+
vendor的问题是在使用`go get -u`更新时,会将工程默认分支的最新版本拉取到本地,不能指定第三方包的版本。
124+
125+
### 4.2 dep
126+
127+
dep可以解决第三方包版本问题:
128+
```
129+
# dep安装
130+
go get -u github.com /golang/dep/cmd/dep
131+
132+
# 测试
133+
dep version
134+
135+
# 初始化一个项目
136+
dep init
137+
```
138+
139+
dep 通过两个元文件来管理依赖 :
140+
- Gopkg.toml:manifest 文件 ,可以由用户自由配置,包括依赖的 source 、 branch 、 version 等。可以通过命令产生,也可以被用户手动修改。
141+
- Gopkg .lock:lock 文件,仅描述工程当前第三方包版本视图,lock 是自动生成的,不可以手动修改。
100142

143+
同样 vendor 目录下存放具体依赖的外部包的代码。
101144

102145

03-工程管理/09-交叉编译.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## 一 交叉编译
2+
3+
### 1.1 Go1.5及之后的交叉编译
4+
5+
Go1.5编译工具链也是使用Go语言书写,Go编译器内置交叉编译功能,只需要时和之GOOS和GOARCH即可进行交叉编译:
6+
```
7+
# 进入源码目录
8+
9+
# 编译为Linux目标文件(如果要编译为win,则GOOS=windows)
10+
GO ENABLED=O GOOS=linux GOARCH=amd64 go build xxx.go
11+
```
12+
13+
### 1.2 Go1.4及之前的交叉编译
14+
15+
Go1.4之前,由于编译器是C语言书写,交叉编译前需要在当前平台构建一个目标平台的编译环境,然后通过设置GOOS和GOARCH进行交叉编译:
16+
```
17+
# 进入源码目录
18+
19+
# 在Linux下构建Win的交叉编译环境
20+
CGO ENABLED=O GOOS=windows GOARCH=amd64 . /make . bash
21+
22+
# 交叉编译
23+
CGO ENABLED= O GOOS=windows GOARCH=amd64 go build xxx.go
24+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## 一 协议
2+
3+
4+
##

0 commit comments

Comments
 (0)