Go 的基本介绍
# 一、语言特性
# 1,简洁易读
- go语言通过设计简洁、清晰的语法和标准库,使得代码更加易读易写;
- 避免了一些语言中常见的复杂特性和概念,如继承和多态等,采用接口实现多态性,减少了冗余代码,提高了代码的可读性;
# 2,并发支持
- go语言内置了原生的并发支持,主要是通过 goroutine 和 channel 实现的;
- goroutine 是一种轻量级的线程,与传统的线程相比,goroutine 的创建和销毁开销更小,因此可以高效地运行成千上万个并发任务,并且可以非常简单的创建一个 goroutine;
- 通过 GMP 调度模型,让用户态的 N 个 goroutine 运行在内核态的 M 个线程上,使得并发任务 goroutine 的切换发生在用户态;
- channel 则提供了在多个 goroutine 之间进行通信和数据交换的机制,避免了共享内存带来的竞争和同步问题;
# 3,内存管理
- go 语言具有自动垃圾回收(Garbage Collection)机制,它基于引用计数和标记-清除算法,定期对无用的对象进行回收,释放内存空间;
- 开发者无需手动管理内存分配与释放,这减轻了开发负担,同时也降低了内存泄漏和指针错位等问题的风险;
# 4,高效编译
- go 语言拥有快速的编译速度,主要是因为它采用了基于单一静态链接库的模块化设计,这种设计方式可以减少编译和链接时的依赖关系,提高编译速度;
- go 语言还采用了增量式编译和缓存技术,可以减少重复编译和提高构建速度。
# 5,跨平台支持
- go 语言提供了丰富的标准库和操作系统接口,可以直接调用操作系统功能,从而实现跨平台支持;
- go 语言提供了对多种操作系统的支持,包括Linux、Windows、macOS等,还提供了对不同 CPU 架构的支持,如x86、ARM等;
# 6,静态类型和类型推断
- go 语言是一种静态类型语言,可以在编译阶段发现一些类型错误,避免了一些运行期错误;
- go 语言还支持类型推断,可以根据上下文自动推导变量的类型,大大简化了代码书写,同时也保留了静态类型语言的安全性;
# 7,强大的工具链
- go 语言提供了丰富的工具链,包括格式化工具、测试工具、性能分析工具等,这些工具能够帮助开发者编写、测试和优化代码,使得开发过程更加高效和可控;
# 二、数据类型
- go 是一种强类型语言,数据类型之间有着严格的区分;
- 常见的数据类型有:
点击查看
bool // 布尔类型,值为 true or false uint8 // 无符号 8 位整形,范围 0 ~ 255 uint16 // 无符号 16 位整形,范围 0 ~ 65535 uint32 // 无符号 32 位整形,范围 0 ~ 4294967295 uint64 // 无符号 64 位整形,范围 0 ~ 18446744073709551615 uint // 64 位机器上等于 uint64,32 位机器上等于 uint32 int8 // 有符号 8 位整形,范围 -128 ~ 127 int16 // 有符号 16 位整形,范围 -32768 ~ 32767 int32 // 有符号 32 位整形,范围 -2147483648 - 2147483647 int64 // 有符号 64 位整形,范围 -9223372036854775808 ~ 9223372036854775807 int // 64 位机器上等于 int64,32 位机器上等于 int32 float32 // 32 位浮点数,符合 IEEE-754 标准 float64 // 64 位浮点数,符合 IEEE-754 标准 string // 字符串类型,可以为空,字符不可改变 complex64 // 64 位复数,实部和虚部都是 float32 complex128 // 128 位复数,实部和虚部都是 float64 uintptr // 整数类型,足够大,可以容纳任何指针的位模式 byte // uint8 的别名,在所有方面都等同于 uint8,用于区分字节值和 8 位无符号整数值 rune // int32 的别名,在所有方面都等同于 int32,用于区分字符值和整数值 nil // 一个预先声明的标识符,表示指针、通道、func、接口、映射或切片类型的零值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 三、数据结构
# 1,slice
- 切片,用于存储一组同类型数据;
- 底层主要是长度、容量、指向数组的指针组成,当触发扩容时,该指针的值会发生变化;
# 2,array
- 固定容量的切片,或是根据存储的数据长度自动推导容量大小;
- 没有 append 函数,不会触发扩容;
- 只能通过索引访问、修改、添加元素;
# 3,map
- 映射结构,用于存储 key、value 的键值对,key 的类型相同,value 的类型也要相同,key 和 value 类型可以不同;
- 底层主要是通过数组和哈希的方式实现,并通过链接地址法处理哈希冲突,同时 key 和 value 是分开存储的,以方便内存对齐和内存回收;
- 当 map 的负载因子达到一定值时会触发扩容;
# 4,struct
- 结构体类型,用于存储不同类型的数据;
- 空结构体的大小为 0;
# 5,interface
- 接口类型,用于定义对象的行为和方法集合;
- 接口提供了一种方式来实现多态性,允许不同的类型以不同的方式进行交互;
- 接口定义了一个或多个方法的签名,但没有具体的实现,任何类型只要实现了接口中定义的所有方法,就被认为是该接口类型的实现;
- 所有类型均是空接口的实现;
# 四、内置函数
# 1,append
func append(slice []Type, elems ...Type) []Type
;- append 内置函数将元素追加到切片的末尾;
- 如果切片有足够的容量,则直接将新元素添加到底层数组;
- 如果没有,将触发扩容分配一个新的底层数组,此时指向数组的指针指会发生改变,append 返回更新后的切片;
# 2,copy
func copy(dst, src []Type) int
;- copy 内置函数将元素从源切片复制到目标切片中;
- 作为特殊情况,它还会将字节从字符串复制到字节切片;
- 源和目标可能重叠,可能会出现意想不到的情况;
- copy 返回复制的元素数,即 len(src) 和 len(dst) 的最小值;
# 3,delete
delete(m map[Type]Type1, key Type)
;- delete 内置函数从映射中删除具有指定键
m[key]
的元素。如果m
为nil
或没有此类元素,则 delete 为空操作。
# 4,len
func len(v Type) int
;- len 内置函数根据其类型返回 v 的长度:
- 数组或数组指针:v 中的元素数量;
- slice 或 map:返回 v 中元素数量,如果 v 为 nil,则 len(v) 为零;
- string:v 中的字节数;
- channel:通道缓冲区中排队(未读)的元素数,如果 v 为 nil,则 len(v) 为零。
# 5,cap
func cap(v Type) int
;- cap 内置函数根据其类型返回 v 的容量:
- 数组或数组指针:v 中的元素数量;(与 len(v) 相同);
- slice:可以达到的最大长度,如果 v 为 nil,则 cap(v) 为零;
- channel:通道缓冲区容量,如果 v 为 nil,则 cap(v) 为零;
# 6,new
func new(Type) *Type
;- 用来分配内存,第一个参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针;
# 7,make
func make(t Type, size ...IntegerType) Type
;- 用来分配并初始化
slice、map、chan
类型的对象; - 与 new 一样,第一个参数是类型,而不是值;与 new 不同的是,make 的返回类型与其参数的类型相同,而不是指向它的指针;
- 参数和结果的规范取决于创建的类型:
slice
:size 指定长度,切片的容量等于其长度。可以提供第二个整数参数来指定不同的容量,必须不小于长度;map
:为空 map 分配足够的空间来容纳指定数量的元素,可以省略 size,在这种情况下,将分配较小的起始大小;chan
:通道的缓冲区使用指定的缓冲区容量进行初始化,如果为零或省略大小,则通道无缓冲;
# 8,close
func close(c chan<- Type)
;- close 内置函数关闭通道,该通道必须是双向的或仅发送的;
- 通道应该只由发送方执行,而不是由接收方执行,并且具有在接收到最后一个发送的值后关闭通道的效果;
- 从关闭后的通道 c 接收到最后一个值后,c 的任何接收 goroutine 都将成功接收到通道元素的零值,而不会被阻塞;
- 对于关闭后的通道,x, ok := <-c 会将 ok 设置为 false;
# 9,panic
func panic(v interface{})
;- panic 内置函数停止当前 goroutine 的正常执行;
- 当函数 F 调用 panic 时,F 的正常执行会立即停止,任何被 F 延迟执行的函数都以平常的方式运行,然后 F 返回给其调用方;
- 对于调用方 G,对 F 的调用就像对 panic 的调用一样,终止 G 的执行并运行任何延迟的函数;
- 这种情况一直持续到执行 goroutine 中的所有函数以相反的顺序停止为止,此时,程序将终止,并带有非零退出代码;
- 此终止序列称为 panicking,可通过内置函数 recover 进行捕获;
# 10,recover
func recover() interface{}
;- recover 内置函数允许程序管理 goroutine 的 panic 行为,且只能捕获当前 goroutine,无法夸 goroutine;
- 在延迟函数(但不是它调用的任何函数)中执行恢复调用会通过恢复正常执行来停止 panic 序列,并检索传递给 panic 调用的错误值;
- 如果在延迟函数之外调用 recover,则不会停止 panic 序列,即 recover 只能在 defer 中执行,在其他作用域无效,且只能在与 panic 同级的 defer 函数中才有效,多级嵌套 defer 后,最里层的 recover 无法捕获外层的 panic;
- 当 goroutine 没有 panic ,或者 panic 的参数为 nil,则 recover 返回 nil;
- recover 的返回值能够说明 goroutine 是否处于 panic 状态;
# 11,print
func print(args ...Type)
;- print 内置函数以特定地实现方式格式化其参数,并将结果写入标准错误;
# 12,println
func println(args ...Type)
;- println 内置函数以特定地实现方式格式化其参数,并将结果写入标准错误;
- 始终在参数之间添加空格,并附加换行符;
# 13,complex
func complex(r, i FloatType) ComplexType
;- complex 内置函数从两个浮点值构造一个复数值;
- 实部和虚部必须具有相同的大小,即 float32 或 float64;
- 并且返回值将是相应的复数类型(float32 为 complex64,float64 为 complex128);
# 14,real
func real(c ComplexType) FloatType
;- real 内置函数返回复数 c 的实数部分,返回值将是与 c 类型对应的浮点类型;
# 15,imag
func imag(c ComplexType) FloatType
;- imag 内置函数返回复数 c 的虚部,返回值将是与 c 类型对应的浮点类型;
# 五、同步原语
# 1,Mutex
- 互斥锁,同一时刻只能被一个 goroutine 拥有;
- 写写、写读、读读均互斥;
# 2,RWMutex
- 读写锁,同一时刻只能被一个写 goroutine 拥有,或同时被多个读 goroutine 拥有;
- 写写、写读互斥,读读不互斥;
# 3,WaitGroup
- 主 goroutine 等待子 goroutine,用于等待一组 goroutine 的返回,例如并发请求后等待结果返回再统一处理;
# 4,Once
- 用于保证运行期间,某段代码只执行一次,例如初始化某个配置;
# 5,Cond
- 子 goroutine 等待主 goroutine,实现了一个条件变量,可以让一组阻塞等待的 goroutine 在满足条件的情况下被唤醒;
# 6,Pool
- 一组可以单独保存和检索的临时对象的集合,可以缓存已分配但未使用的对象供以后重用,从而减轻垃圾回收器的压力;
# 7,atomic
- 提供了一系列的函数,用于对基本数据类型(如整数、指针)进行原子操作,包括读取、存储、加法、减法、比较等;
# 六、关键字
# 1,for
# 2,range
# 3,defer
# 4,select
# 5,channel
# 6,reflect
提示
持续更新中……
编辑 (opens new window)
上次更新: 2024/03/18, 13:10:19