1. 数据类型
1.1 Go数据类型
类型 | 长度 | 默认值 | 说明 |
---|---|---|---|
bool | 1 | false | |
byte | 1 | 0 | uint8的别名,相互不需要转换 |
int, uint | 4, 8 | 0 | 默认整型,长度依平台而定,32或64 |
int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255 |
int16, uint16 | 2 | 0 | |
int32, uint32 | 4 | 0 | |
int64, uint64 | 8 | 0 | |
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | 默认 |
complex64 | 8 | ||
complex128 | 16 | ||
rune | 4 | 0 | Unicode Code Point, int32的别名 |
uintptr | 4, 8 | 0 | 存储指针的uint |
string | “” | 默认值空字符串,而非nil | |
array | 数组 | ||
struct | 结构体 | ||
function | nil | ||
interface | nil | ||
map | nil | 字典,引用类型 | |
slice | nil | 切片,引用类型 | |
channel | nil | 通道,引用类型 | |
1.2 值类型和引用类型
值类型:基本数据类型(int, float, bool, string)、数组(array)和结构体(struct)
- 变量直接存储,内存通常在栈中分配 (栈区:存放生命周期较短的数据)
引用类型:ptr、slice、map、channel、interface
- 变量存储的是一个地址,该地址对应的空间才真正存储数据。内存通常在堆上分配。当没有任何变量引用这个地址时,该地址对应的数据空间就成了垃圾,由GC来回收。(堆区:存放生命周期较长的数据。一个值类型,一般存储在栈区,但它如果在别的函数也用到,此时有可能放堆区,它要做逃逸分析)
2. 基本数据类型
2.1 const常量
2.1.1 常量特性:
- readonly
- cannot get address
1 | const x = 0x100 |
2.1.2 常量初始化和枚举:
iota
: 常量计数器
1 | const ( |
2.2 数值类型
2.2.1 类型转换
必须显示转换,不支持像Java一样向上自动转换
1 | byte // uint8, 处理ASCII字符 |
2.2.2 运算符
1 | // 除法 |
2.2.3 两个变量,进行值交换,不允许使用中间变量
1 | var a int = 3 |
2.2.4 数值进制转换
1 | func main() { |
2.2.5 数值类型转换
1 | func main() { |
2.2.6 处理浮点数
1 | func main() { |
2.2.7 浮点数精度问题
1 | func main() { |
2.3 字符串
本质:是一个不可变byte序列,本身是一个复合结构
1 | type stringStruct struct { |
头部指针指向字节数组,但没有NULL结尾
原始字符串raw string
: 使用反引号”`”包裹,支持跨行
2.3.1 元素
允许索引方式访问元素,但不能获取元素地址
1 | func main() { |
2.3.2 切片
切片语法返回的子字符串,其内部依旧指向原始数组
reflect.StringHeader
和string头结构相同unsafe.Pointer
用于指针类型转换
1 | func main() { |
2.3.3 字符串遍历
1 | func main() { |
2.3.4 修改字符串
字符串对象不可变,要修改,先将其转换为可变类型 []rune
或[]byte
1 | s := "hello world" |
2.3.5 处理Unicode
1 | func main() { |
2.3.6 截取字符串
1 | func main() { |
2.3.7 字符串拼接性能
测试命令: go test -bench=.
1) 较差
1 | func test() string { |
2) 改进1 strings.Join(sa, "")
1 | func test() string { |
3) 改进2 byte.Buffer
1 | func test() string { |
2.3.8 字符串常用函数
1 | len("abc") |
2.3.9 获取中文字符串长度:
1 | var str = "hello 你好" |
2.4 数组
2.4.1 声明和初始化
1 | // 声明 |
2.4.2 数组遍历
1 | func main() { |
2.4.3 二分查找
二分查找逻辑:
- 数组必须有序arr
- 中间的下标:midIndex = (firstIndex + lastIndex) / 2
- 让arr[midIndex]与targetValue比较
- arr[midIndex] > targetValue,返回firstIndex … (midIndex-1)
- arr[midIndex] < targetValue,返回(midIndex+1) … lastIndex
- arr[midIndex] == targetValue,找到
1 | func main() { |
2.4.4 多维数组
只允许第一维缺省
1 | func main() { |
2.4.5 数组长度
len
和cap
都只返回一维数组长度
1 | func main() { |
2.4.6 比较操作
如元素类型支持“==、!=”操作符,那么数组也支持此操作。
前提:类型必须一致!
1 | func main() { |
2.4.7 指针数组和数组指针
- 指针数组: 元素为指针类型的数组
- 数组指针: 数组变量的地址
1 | func main() { |
使用指针操作数组:
1 | func main() { |
2.4.8 数组复制
1 | func test1(x [2]int) { |
2.4.9 排序算法
1 | func main() { |