1、使用与代码所在文件夹一样的名字作为包名。
2、将工厂函数命名为New是Go语言的一个习好惯。
// counters包提供告警计数器的功能
package counters
// alertCounter是一个未公开的类型
// 这个类型用于保存告警计数
type alertCounter int
// New创建并返回一个未公开的
// alertCounter类型的值
func New(value int) alertCounter {
return alertCounter(value)
}
3、类型的本质
声明一个该类型的方法之前,需要先回答一个问题:这个类型的本质是什么。如果给这个类型增加或者删除某个值,是要创建一个新值,还是要更改当前的值?如果是要创建一个新值,该类型的方法就使用值接收者。如果是要修改当前值,就使用指针接收者。
保持传递的一致性很重要。这个背后的原则是,不要只关注某个方法是如何处理这个值,而是要关注这个值的本质是什么。
1)内置类型
内置类型是由语言提供的一组类型。我们已经见过这些类型,分别是数值类型、字符串类型和布尔类型。这些类型本质上是原始的类型。因此,当对这些值进行增加或者删除的时候,会创建一个新值。基于这个结论,当把这些类型的值传递给方法或者函数时,应该传递一个对应值的副本。
2)引用类型 :切片、映射、通道、接口和函数类型 。当声明上述类型的变量时,创建的变量被称作标头(header)值。
因为标头值是为复制而设计的,所以永远不需要共享一个引用类型的值。标头值里包含一个指针,因此通过复制来传递一个引用类型的值的副本,本质上就是在共享底层数据结构。
3)结构类型
结构类型可以用来描述一组数据值,这组值的本质即可以是原始的,也可以是非原始的
4、go 中的接口是对一组行为的建模
5、Go 语言的接口更小,只倾向于定义一个单一的动作。
6、一个包定义一组编译过的代码,包的名字类似命名空间,可以用来间接访问包内声明的标识符
7、所有处于同一个文件夹里的代码文件,必须使用同一个包名。按照惯例,包和文件夹同名。
8、导入的路径前面有一个下划线,如 _ "github.com/goinaction/code/chapter2/sample/matchers"
这个技术是为了让Go语言对包做初始化操作,但是并不使用包里的标识符。为了让程序的可读性更强,Go 编译器不允许声明导入某个包却不使用。下划线让编译器接受这类导入,并且调用对应包内的所有代码文件里定义的init函数。
9、程序中每个代码文件里的init函数都会在main函数执行前调用。
10、包级变量
11、根据经验,如果需要声明初始值为零值的变量,应该使用var关键字声明变量;如果提供确切的非零值初始化变量或者使用函数返回值创建变量,应该使用简化变量声明运算符。
12、在Go语言中,如果main函数返回,整个程序也就终止了。Go程序终止时,还会关闭所有之前启动且还在运行的goroutine。写并发程序的时候,最佳做法是,在main函数返回前,清理并终止所有之前启动的goroutine。编写启动和终止时的状态都很清晰的程序,有助减少bug,防止资源异常。
13、查找map里的键时,有两个选择:要么赋值给一个变量,要么为了精确查找,赋值给两个变量。赋值给两个变量时第一个值和赋值给一个变量时的值一样,是 map 查找的结果值。如果指定了第二个值,就会返回一个布尔标志,来表示查找的键是否存在于map里。
14、指针变量可以方便地在函数之间共享数据。
15、在Go语言中,所有的变量都以值的方式传递。因为指针变量的值是所指向的内存地址,在函数间传递指针变量,是在传递这个地址值,所以依旧被看作以值的方式在传递。
16、关键字defer会安排随后的函数调用在函数返回时才执行。在使用完文件后,需要主动关闭文件。使用关键字defer来安排调用Close方法,可以保证这个函数一定会被调用。哪怕函数意外崩溃终止,也能保证关键字defer安排调用的函数会被执行。
17、如果接口类型只包含一个方法,那么这个类型的名字以er结尾。我们的例子里就是这么做的,所以这个接口的名字叫作Matcher。如果接口类型内部声明了多个方法,其名字需要与其行为关联。
18、空结构在创建实例时,不会分配任何内存。这种结构很适合创建没有任何状态的类型。
19、同一个目录下的所有.go文件必须声明同一个包名。 给包命名的惯例是使用包所在目录的名字。给包及其目录命名时,应该使用简洁、清晰且全小写的名字,这有利于开发时频繁输入包名。例如,net/http包下面的包,如cgi、httputil和pprof,名字都很简洁
20、包更常用来指语义上可导入的功能单元。
21、。命名导入是指,在import语句给出的包路径的左侧定义一个名字,将导入的包命名为新名字。
22、如果想给包写一段文字量比较大的文档,可以在工程里包含一个叫作doc.go的文件,使用同样的包名,并把包的介绍使用注释加在包名声明之前。
/*
*/
包usb提供了用于调用USB设备的类型和函数。想要与USB设备创建一个新链接,使用NewConnection
...
package usb
23、go 语言没有为构造函数提供特殊的语言特性,而是选择了名称格式为 newType 或者 NewType 的函数用于构造指定类型的值。
24、代码可以通过接口表达抽象的概念
25、按照惯例,接口类型的名称常常会以 - er 作为后缀。
26、go 语言允许在实现代码的过程中随时创建新的接口。任何代码都可以实现接口,包括哪些已经存在的代码。
27、go 通过简单的、通常只有一个方法的接口......来鼓励组合而不是继承,这些接口在各组件之间形成了简明易懂的界限。
28、使用指针作为接收者的策略应该是始终如一的。如果一种类型的某些方法需要用到指针作为接收者,就应该为这种类型的所有方法都使用指针作为接收者。
29、泛型 https://segmentfault.com/a/1190000041634906