Go程序结构
1.命名规则
名称的开头是一个字母或下划线,后面跟任意数量的字符、数字和下划线,并区分大小写。
2.关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
3.预声明常量,类型和函数
常量: true false iota nil
类型: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64
uintptr float32 float64 complex64 complex128
bool byte rune string error
函数: make len cap new append
copy close delete complex real
imag panic recover
这些名称不是预留的,可以在声明中使用它们,也就是可以声明跟这此名字一样的常量,类型或函数。
4.声明
- 有四个主要的声明:变量(var)、常量(const)、类型(type)和函数(func)。
- package声明后面是import声明,然后是包级别的类型、变量、常量、函数的声明,不区分顺序。包级别的实体名字不仅对于包含其声明的源文件可见,而且对于同一个包里面的所有源文件都可见。
- 如果一个实体在函数中声明,它只在函数局部有效。如果声明在函数外,它将对包里面的所有源文件可见。实体第一个字母的大小写决定其可见性是否跨包。如果名称以大小写字母开头,它是导出的,意味着它对包修是可见和可访问的。
5.变量
声明的通用形式
var name type = expression
var name = expression
var name type
声明时没有赋值的,go会默认赋予相应类型的零值——数字是0,布尔值是false,字符串是"", 接口和引用类型(slice,指针,map,通道、函数)是nil.
go里面不存在未初始化的变量。忽略类型允许声明多个不同类型的变量。
var i,j,k int
var b,f,s = true,2.3,"four"
包级别的初始化在main开始之前进行
6.短变量声明
在函数中可用 ==name := expression== 这种形式来声明和初始化局部变量,这样的声明形式就是短变量声明。多个变量可使用短变量声明形式同时声明。记住:=表示声明,而=表示赋值。短变量声明不需要声明所有在左边的变量,但是,短变量声明最少要声明一个新变量。
7.指针
- 指针的值是一个变量的地址。一个指针指示值所保存的位置。
- 不是所有值都有地址(比如基础类型的字面量),但是所有的变量都有。
- 使用指针,可以在无须知道变量名字的情况下间接读取可更新变量的值。
- 指针是可比较的,两个指针当且仅当指向同一个变量或者两者都是ni的情况下才相等。
- 传递指针参数给函数,能够让函数更新间接传递的变量值。
- 每次使用变量的地址或者复制一个指针,就会创建新的别名或者方式来标记同一变量。
8.new函数
new函数用来创建变量,表达式new(T)创建一个未命名的T类型变量,初始化为T类型的零值,并返回其地址(地址类型为*T)。
9.变量的生命周期
生命周期是指在程序执行过程中变量存在的时间段。包级别变量的生命周期是整个程序的执行时间。局部变量有一个动态的生命周期,变量从被声明时开始直到变得不可访问。函数的参数和返回值也是局部变量,它们在其闭包函数被调用的时候创建。变量的生命周期是通过它是否可达来确定的。
10.变量逃逸
当一个局部变量在其闭包函数外仍可被访问时,局部变量就会发生变量逃逸。
11.可赋值性
一个函数调类型T,都有一个对应的类型转换操作T(x)将值x转换为类型T。如果两个类型具有相同的底层类型或二者都是指向相同底层类型变量的未命名指针类型,则二者是可以相互转换的。类型转换不改变类型值的表达方式,仅改变类型。
12.包和文件
每一个包给它的声明提供独立的命名空间。包让我们可以通过控制变量在包外面的可见性或导出情况来隐藏信息,标记符是否可对外可见,取决于标识符是否以大小写开头。第一个包里只有一个文件应该包含该包的文档注释。
14.包的初始化
包的初始化从初始化包级别的变量开妈,这些变量按照声明顺序初始化,在依赖已解析完毕的情况下,根据依赖的顺序进行。
一些复杂的变量需要借助init函数来初始化,任何go文件可以包含任意数量的声明如下的函数:
func init(){/*...*/}
init函数不能被调用和被引用,另一方面,它也是普通的函数。在每一个文件中,当程序启动的时候,init函数按照它们声明的顺序自动执行。
包的初始化按照在程序中导入的顺序来进行,依赖顺序优先,每次初始化一个包。初始化是过程是自下向上的,main包最后初始化。所以,在main函数开开始执行前,所有包已初始化完毕。
15.作用域
声明的作用域是声明在程序文本中出现的区域,它是一个编译时属性。在包级别的(就是任何函数外)的声明,可以被同一个包里的任何文件引用。一个程序可以包含多个同名的声明,前提是它们在不同记忆法块中。不是所有词法块都对应于显式大括号包围的语句序列,有一些记忆法块是隐式的。for循环会创建两个词法块,一个是循环体本身的显式块,以及一个隐式块,它包含了一个闭合结构,其中就有初始化语句中声明的变量。
在包级别,声明顺序和它们的作用域没有关系,所以一个声明可以引用它自己或者跟在它后面的其他声明,使我们可以声明递归或相互递归的类型和函数
ps:短变量声明依赖一个明确的作用域。