夜雪天狼
学习笔记
技术博文
转载备份
心灵鸡汤
目录
散碎知识点及常见错误
发布者:caijw
阅读量:61000
发布时间:2018-10-30 11:04:31
# 散碎知识点与技巧 -vertical- ## 错误类型 Go内置有一个`error`类型,专门用来处理错误信息,Go的`package`里面还专门有一个包`errors`来处理错误: ```go err := errors.New("emit macho dwarf: elf header corrupted") if err != nil { fmt.Print(err) } ``` -vertical- ## 分组声明 在Go语言中,同时声明多个常量、变量,或者导入多个包时,可采用分组的方式进行声明 ```go import "fmt" import "os" const i = 100 const pi = 3.1415 const prefix = "Go_" var i int var pi float32 var prefix string //可以分组写成如下形式: import( "fmt" "os" ) const( i = 100 pi = 3.1415 prefix = "Go_" ) var( i int pi float32 prefix string ) ``` -vertical- ## iota枚举 Go里面有一个关键字iota,这个关键字用来声明enum的时候采用,它默认开始值是0,每调用一次加1 ```go const( x = iota // x == 0 y = iota // y == 1 z = iota // z == 2 w // 常量声明省略值时,默认和之前一个值的字面相同。这里隐式地说w = iota,因此w == 3。其实上面y和z可同样不用"= iota" ) const v = iota // 每遇到一个const关键字,iota就会重置,此时v == 0 const ( e, f, g = iota, iota, iota //e=0,f=0,g=0 iota在同一行值相同 ) ``` Comment: 除非被显式设置为其它值或iota,每个const分组的第一个常量被默认设置为它的0值,第二及后续的常量被默认设置为它前面那个常量的值,如果前面那个常量的值是iota,则它也被设置为iota -separator- # make、new操作 * `make`用于内建类型(`map`、`slice` 和`channel`)的内存分配 * `new`用于各种类型的内存分配 -vertical- ## new 内建函数`new`本质上说跟其它语言中的同名函数功能一样:`new(T)`分配了零值填充的`T`类型的内存空间,并且返回其地址,即一个`*T`类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型`T`的零值 Comment: 有一点非常重要:`new返回指针` -vertical- ## make 内建函数`make(T, args)`与`new(T)`有着不同的功能,make只能创建`slice`、`map`和`channel`,并且返回一个有初始值(非零)的`T`类型,而不是`*T` 本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化 例如,一个`slice`,是一个包含指向数据(内部`array`)的指针、长度和容量的三项描述符;在这些项目被初始化之前,`slice`为`nil`。对于`slice`、`map`和`channel`来说,`make`初始化了内部的数据结构,填充适当的值 -separator- # 常见错误 -vertical- ## 永远不要使用形如 var p*a 声明变量 ```go package main import "fmt" func main() { var x int = 6 var p *int = &x fmt.Println(p) var y*int = &x fmt.Println(y) } ``` Comment: 在书写表达式类似 var p *type 时,切记在 * 号和指针名称间留有一个空格,因为 - var p*type 是语法正确的,但是在更复杂的表达式中,它容易被误认为是一个乘法表达式 -separator- ## 误用短声明导致变量覆盖 ```go var remember bool = false if something { remember := true //错误,这里应该使用=而不是:= } // 使用remember ``` Comment: 在此代码段中,remember变量永远不会在if语句外面变成true,如果something为true,由于使用了短声明:=,if语句内部的新变量remember将覆盖外面的remember变量,并且该变量的值为true,但是在if语句外面,变量remember的值变成了false -separator- # 出于性能考虑的最佳实践和建议 1. 尽可能的使用:=去初始化声明一个变量(在函数内部) 2. 尽可能的使用字符代替字符串 3. 尽可能的使用切片代替数组 4. 当定义一个方法时,使用指针类型作为方法的接受者 5. 尽可能在需要分配大量内存时使用缓存 -separator-