## 一、基础知识
##### [思维导版本](https://github.com/0voice/learning_mind_map#-golang)
### 流程控制语句
#### for循环
1. 接一个条件表达式
2. 接三个表达式
3. 接一个 range 表达式
- 可以用于读取slice和map的数据
- 使用_来丢弃不需要的返回值
4. 不接表达式
#### if判断
条件判断语句里面允许声明一个变量,这个变量的作用域只能在该条件逻辑块内,其他地方不起作用
#### switch选择
### 变量/常量
#### 声明变量
**单个变量**
1. 不赋值:var i int
2. 赋值:var i = 10.11 var i int = 10
3. 匿名变量:短下划线 _,忽略
**多个变量**
1. var n1,n2,n3 int
2. var n1,n2, n3 = 100,"tom",888
3. n1,n2,n3 := 100,"tom",888
#### 声明常量
- 关键字const,也可重置
- 可以不赋值,同上一行的值
- iota计数器,枚举
#### 注意
- 在同一范围内可变
- 变量 = 变量名 + 值 + 数据类型
- String默认空挡,小数默认为0
### 运算符
#### 算术运算符
```
+
\-
*
/
%
++/-- 是语句,不是运算符
```
#### 关系运算符
```
==
!=
\>
\>=
<
<=
```
#### 逻辑运算符
```
&&
||
!
```
#### 位运算符
```
&:二进制加法运算,都是1就是1
|:有一个是1就是1
^:不一样就是1
<<:左移,×2
\>>:右移,/2
```
#### 赋值运算符
```
=
+=
-=
*=
/=
%=
<<=
\>>=
&=
|=
^=
```
### 转义字符
```
\t 一个制表符,中间有空格
\n 换行符
\ 在输出路径的时候用
\" 一个“
\r 一个回车,从顶头开始输,覆盖掉前面的
```
### 格式化输出
#### 布尔值
- %t 单词true或false
#### 整数
- %b 二进制表示
- %c 相应Unicode码点所表示的字符
- %d 十进制表示
- %o 八进制表示
- %q 单引号围绕的字符字面值,由Go语法转义
- %x 十六进制表示,字母形式为小写 a-f
- %X 十六进制表示,字母形式为大写 A-F
- %U Unicode格式:123,等同于 "U+007B"
#### 浮点数、复数
- %b 无小数部分、二进制指数的科学计数法,
- %e 科学计数法,例如 -1234.456e+78
- %E 科学计数法,例如 -1234.456E+78
- %f 有小数点而无指数,例如 123.456
- %G 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
- %g 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的0)输出
#### 字符串和[]byte
- %q 双引号围绕的字符串,由Go语法转义
- %s 字符串或切片的无解译字节
- %x 十六进制,小写字母,每字节两个字符
- %X 十六进制,大写字母,每字节两个字符
#### 指针
- %p 表示为十六进制,并加上前导的0x
#### 通用占位符
- %v 值的默认格式。
- %+v 类似%v,但输出结构体时会添加字段名
- %#v 相应值的Go语法表示
- %T 相应值的类型的Go语法表示
- %% 百分号,字面上的%,非占位符含义
## 二、数据类型
### 基本数据类型
#### 数值型
##### 整数型
1. int/int8/int16/int32/int64
2. uint/uint8/uint16/uint32/uint64/byte
3. 类型 :int,unit,rune(int32),byte(uint8)
##### 浮点型
1. float 32
2. float64(默认)
##### 复数
1. complex128
2. complex64
#### 字符型
- 占用空间是用unsafe.sizeof(参数)
#### 布尔型(bool)
- 默认false
- 不参与运算和转换
#### 字符串(string)
1. 反引号''字符串以原生形式输出
2. 长度:len(变量名)
3. 分割:strings.Split(变量名,“切割标准”)
4. 包含:strings.Contains(变量名,“包含内容”)
5. 前缀:strings.HasPrefixstrings.
6. 后缀:strings.HasSuffix
7. 判断位置: strings.Index
8. 最后出现的位置:strings.LastIndex
9. join拼接:strings.Join(变量名, “符号”)
### 复杂数据类型
#### 指针(Pointer)
1. 声明一个指针
2. var p *int
3. 指向一个内存地址
4. p = &a
5. 不分配变量,值为nil
6. 永远正确:var == *(&var)
7. 适用环境:函数可以直接修改参数的值,而不是对参数的副本进行操作--引用传递
#### 数组
##### 定义
var 数组名 [数量]类型
##### 初始化
**不赋值**
- var testArray [3]int
**赋值**
- var testArray [3]int{1,2}
- 长度:var testArray [...]int{1,2}
- 索引:a := [...]int{1: 1, 3: 2}
##### 嵌套数组
```go
doubleArray := [2][4]int
{
[4]int{1, 2, 3, 4},
[4]int{5, 6, 7, 8}
}
easyArray := [2][4]int
{
{1, 2, 3, 4},
{5, 6, 7, 8}
}
```
##### 遍历
- for *3
- for range
#### 管道(Channel)
#### 切片(slice)
- **ar[:n]等价于ar[0:n]**
- **ar[n:]等价于ar[n:len(ar)]**
- **ar[:]等价于ar[0:len(ar)]**
- **内置函数**
- len 获取slice的长度
- cap 获取slice的最大容量
- append 向slice里面追加一个或者多个元素
- copy 函数copy从源slice的src中复制元素到目标dst,并且返回复制的元素的个数
#### 接口(interface)
#### map
##### 格式: map[keyType]valueType
##### 特点:
1. map是无序的,必须通过key获取
2. 引用类型,长度不固定
3. len函数返回map拥有的key的数量
##### make(T, args)
1. map、slice 和channel
2. 返回一个有初始值(非零)的T类型:零值
- int 0
- int8 0
- int32 0
- int64 0
- uint 0x0
- rune 0 //rune的实际类型是 int32
- byte 0x0 // byte的实际类型是 uint8
- float32 0 //长度为 4 byte
- float64 0 //长度为 8 byte
- bool false
- string ""
##### new(T)
- 各种类型的内存分配
- new返回指针
## 三、与Java比较
### 相同
1. 引入包
2. 垃圾回收机制
3. 管道通信机制
4. 严格区分大小写
5. 同一个包下两个main函数会报错
### 不同
1. 指针
2. 天然并发
3. 返回值可多个
4. 语句后不用带分号
5. 变量搁到类型前
6. 切片slice/延时执行defer
7. 引了包/变量没用会注销
8. 一行执行一条语句
## 四、进阶知识
### 反射
**func (t *rtype) String() string**
获取 t 类型的字符串描述,不要通过 String 来判断两种类型是否一致。
**func (t *rtype) Name() string**
获取 t 类型在其包中定义的名称,未命名类型则返回空字符串。
**func (t *rtype) PkgPath() string**
获取 t 类型所在包的名称,未命名类型则返回空字符串。
**func (t *rtype) Kind() reflect.Kind**
获取 t 类型的类别。
**func (t *rtype) Size() uintptr**
获取 t 类型的值在分配内存时的大小,功能和 unsafe.SizeOf 一样。
**func (t *rtype) Align() int**
获取 t 类型的值在分配内存时的字节对齐值。
**func (t *rtype) FieldAlign() int**
获取 t 类型的值作为结构体字段时的字节对齐值。
**func (t *rtype) NumMethod() int**
获取 t 类型的方法数量。
**func (t *rtype) NumField() int**
返回一个struct 类型 的属性个数,如果非struct类型会抛异常
**func (t *rtype) Method() reflect.Method**
根据索引获取 t 类型的方法,如果方法不存在,则 panic。
如果 t 是一个实际的类型,则返回值的 Type 和 Func 字段会列出接收者。
如果 t 只是一个接口,则返回值的 Type 不列出接收者,Func 为空值。
**func (t *rtype) MethodByName(string) (reflect.Method, bool)**
根据名称获取 t 类型的方法。
**func (t *rtype) Implements(u reflect.Type) bool**
判断 t 类型是否实现了 u 接口。
**func (t *rtype) ConvertibleTo(u reflect.Type) bool**
判断 t 类型的值可否转换为 u 类型。
**func (t *rtype) AssignableTo(u reflect.Type) bool**
判断 t 类型的值可否赋值给 u 类型。
**func (t *rtype) Comparable() bool**
判断 t 类型的值可否进行比较操作
注意对于:数组、切片、映射、通道、指针、接口
**func (t *rtype) Elem() reflect.Type**
获取元素类型、获取指针所指对象类型,获取接口的动态类型
**使用**
- 通过反射获取结构体成员类型
- 通过反射获取对象值
- 创建对象和调用方法
有疑问加站长微信联系(非本文作者)