Go语言趣学指南
进度
完成
代码仓库:https://github.com/xiaozhiliaoo/go-practice/tree/master/get-programming-with-go
笔记
-
大数:big。无类型常量:存储非常大的值,被用作函数参数的时候,必须转换为有类型变量
-
字符串不可变,使用UTF-8可变长度编码,每个字符占1~4字节内存。字符串转换可用strconv包。
-
方法是和特定类型关联的函数,关联的类型是方法名的接收者来指定。
-
函数作为一等值便于代码拆分和复用,想要动态创建函数,使用带闭包特性的匿名函数。
-
array作为传参会被复制,slice和map不会被复制。
-
Go 通过结构实现组合,并通过名为结构嵌入的特殊语言特性实现方法转发。
-
使用继承相比,使用组合构建的软件通常更灵活、复用程度更高并且更容易修改。
-
Go 语言通过组合结构和方法,在没有引入任何新特性的情况下实现了传统语言的面向对象特性。构造函数是普通函数,不是特殊的语言特性。
-
对传统继承的使用并不是必需的;所有使用继承解决的问题都可以通过其他方法解决。
-
写入接口Writer,可以将任意内容写入任何地方。
-
类型关心自己存储了什么值,但是接口关心可以做什么而不是存储了什么值。类型通过方法表达自己的行为,而接口则通过列举类型必须满足的一组方法来进行声明。
-
同时使用组合和接口将构成非常强大的设计工具。
-
fmt 包声明Stringer接口,一种类型只要提供了String 方法,它的值就能够为Println、Sprintf 等打印函数所用。
-
Go 通过简单的、通常只有单个方法的接口,来鼓励组合而不是继承,这些接口在各个组件之间形成了简明易懂的界限。 - Rob Pike
-
地址操作符 & 解引用 * ,指针类型 * int 。指针存储的是内存地址。
-
星号放在类型前面:声明指针类型,星号放在变量前面:解引用变量指向的值。
-
在访问字段时对结构体进行解引用并不是必需的。
-
地址操作符可以合法地放置在变量和复合字面量前面,但不能放置在字符串字面量或整数字面量前面。
-
go会对指向结构体,数组指针进行自动解引用,但不对slice和map自动解引用。
-
映射在被赋值或者被作为实参传递的时候不会被复制。因为映射实际上就是一种隐式指针。
-
隐式指针:1 映射也是指针 2 切片指向数组
-
Go 语言的函数和方法都以传值方式传递形参,这意味着函数总是基于被传递实参的副本进行操作。当指针被传递至函数时,函数将接收到传入内存地址的副本,在此之后,函数就可以通过解引用内存地址来修改指针指向的值。
-
使用指针作为接收者的策略应该是始终如一的。如果一种类型的某些方法需要用到指针作为接收者,就应该为这种类型的所有方法都使用指针作为接收者。
-
实现修改:将指针作为形参,将指针作为接受者。
-
nil函数值,nil切片(vs 空切片),nil映射,nil接口
-
slice的零值是nil,代表没有对应的底层数组,map的零值是nil,代表没有引用任何hash表。结构体的零值是结构体成员的零值。指针的零值为nil。
-
在发生错误时,调用返回的其他值可能会被设置成相应类型的零值,但也可能会包含不完整的数据或者完全不同的其他内容。总体来说,每当有错误发生时,同一调用返回的其他值通常就不再值得信任。
-
Go 语言鼓励使用者思考并处理函数可能返回的所有错误。
-
减少错误处理代码的一种策略是,将程序中不会出错的部分和那些包含潜在出错隐患的部分隔离开来。
-
因为错误也是值,所以Go 编程语言提供的所有功能都可以用于处理它们。
-
Go 程序将使用带有Err 前缀的变量来存储错误消息。
-
类型断言:值从接口类型重新转换成底层的具体类型。err.(SudokuError) error类型转换成SudokuError。
-
Go 语言的错误值机制促使开发者考虑错误,而不是像处理异常那样默认将其忽略,这有助于生成更为可靠的软件。除此之外,因为错误值机制不需要用到特殊关键字,所以它比异常简单而灵活。
-
如果某个被defer的函数调用了recover,那么panic将会停止,而程序则会继续运行。这种恢复机制类似于其他语言中的catch、except 和rescue。
-
Go处理错误通过error,没有异常机制。Java处理错误是通过异常机制。
-
并发任务之间则通过相互通信来达成共同的目的。
-
单个通道(都产生相同类型的值)来等待多个goroutine,select处理多个通道。
-
被阻塞的goroutine 并不消耗任何资源。goroutine 会静静地停在那里,等待导致它阻塞的事情发生,然后解除阻塞。
-
“从通道里面读取值,直到它被关闭为止”,所以Go通过在range 语句里面使用通道,程序可以在通道被关闭之前,一直从通道里面读取值。
-
range 语句可以从通道中读取所有值,直到通道关闭为止。
-
互斥锁并未内置在Go 语言当中,而是通过sync 包提供,而通道是内置的。
-
将sync.Mutex 用作结构成员的做法是一种常见的模式。
-
为了保证互斥锁的使用安全,遵守以下规则:尽可能地简化互斥锁保护的代码,对每一份共享状态只使用一个互斥锁。
-
长时间运行的工作进程:
func worker() { for { select { // 在此处等待通道 } } }
-
通道常常被看作是实现细节,所以一般都会把通道隐藏在方法的后面。
-
通道可以发送任何类型的值。