Go 程序的基本结构和要素
包(pkg):结构化代码的一种方式,类似其他语言的类库和命名空间的概念,每个GO文件仅属于一个包。
文件名和包名一般不相同
// 表示一个可独立执行的程序,每一个GO应用程序都包含一个名为main的包
package main
如果打算编译的包名不是main,如pack1,编译后产生的对象将会是pack1.a,而不是可执行程序
包名不是main的包,怎么进行编译生成.a文件?
需要注意,每个包名都应该使用小写字母
包名以.a结尾
标准库
在GO安装文件里包含了一些可以直接使用的包,即标准库
一般情况,标准包放在
G
O
R
O
O
T
/
p
k
g
/
GOROOT/pkg/
GOROOT/pkg/GOOS_$GOARCH/ 下
编译
构建一个程序,包和包内的文件必须以正确的顺序进行编译,包的依赖关系决定了其构建顺序。
属于同一个包的源文件必须全部被一起编译,一个包即是编译时的一个单元,因此按惯例,每个目录都只包含一个包??
如果对一个包进行更改或重新编译,所有引用了这个包的客户端程序都必须全部重新编译。
Go中的包模型采用显示依赖关系的机制
来达到快速编译的目的,编译器会从后缀为.o的文件(需要切只需要这一个文件
)中提取依赖关系
// 显示依赖关系解释
// 如果 A.go 依赖 B.go,而 B.go 又依赖 C.go
// 为了编译 A.go, 编译器读取的是 B.o 而不是 C.o
// 针对大型项目的编译,此机制可显著提升编译速度
每一段代码只会被编译一次
GO中使用import将一组包链接在一起
包导入方式
import “fmt”
import "runtime"
import "fmt";"runtime"
// 推荐
import (
"fmt"
"runtime"
)
// 此方式会被gofmt强制换行
import ("fmt";"runtime")
还需要注意:
1.导入包按字母顺序排列,这样更清晰易读。
包查找方式
// 会在全局文件中进行查找
import “fmt”
// 在相对目录中查找
import "./xxx"
// 在系统绝对路径中查找
import "/sdfsdf"
包别名
import fm "fmt"
import (
fm "fmt"
)
函数
main函数是每一个可执行程序必须包含的,一般都是在启动后第一个执行的函数,如果有init函数会先执行init函数
main包中必须包含main方法,不然会发生构建错误
main函数既没有参数,也没有返回类型
,如果为main函数添加了参数或者返回类型,会引发构建错误
程序是否正确执行
程序正常退出的代码为0,如果程序因异常终止,会返回非零值。这个数值可用来测试是否成功执行一个程序
注释
注释不会被编译,但可以通过 godoc
来使用
每一个包都应该有相关注释,在package语句之前的块注释被默认认为是这个包的文档说明,其中应该提供一些相关信息并对整体功能做简要的介绍
一个包可以分散在多个文件中,但是只需要在其中一个进行注释说明即可,当开发人员需要了解包的情况时,自然会用godoc来显示包的文档说明
另外在多行注释之间应该以空行分割加以区
分
几乎所有的全局作用域的类型、常量、变量、函数和被到处的对象都应该有一个合理的注释
如果这种注释(文档注释)出现在函数前,则要以函数名作为开头
// enterOrbit
causes Superman to fly into low Earth orbit, a position
// that presents several possibilities for planet salvation.
func enterOrbit
() error {
…
}
查看包以及方法信息
// 查看包的主要信息
godoc fmt
// 查看fmt包中的Println方法信息
go doc fmt.Println
类型
基本类型
int,float,bool,string
结构化的(复合型参数):没有真正的值,它使用nil作为默认值
struct、array、slice、map、channel
只描述类型的行为的
interface
Go语言中不存在类型继承
类型转换必须是显示转换,就像调用一个函数一样,类型在这里可以看作一个函数
valueOfTypeB = typeB(valueOfTypeA)
一个函数可以有多个返回值,返回类型之间需要使用逗号分割,并使用小括号()将他们括起来
这种多返回值一般用于判断函数是否执行成功,或与其它返回值一同返回错误消息
type可以定义一个已经存在的类型的别名
type IZ int
这里不是真正意义上的别名,因为使用这种方法定义之后的类型可以拥有更多的特性
GO程序的一般结构
1.在完成包的 import 之后,开始对常量、变量和类型的定义或声明
2.如果存在 init 函数的话,则对该函数进行定义(这是一个特殊的函数,每个含有该函数的包都会首先执行这个函数)。
3.如果当前包是 main 包,则定义 main 函数。
4.然后定义其余的函数,首先是类型的方法,接着是按照 main 函数中先后调用的顺序来定义相关函数,如果有很多函数,则可以按照字母顺序来进行排序。
GO程序的执行顺序
1.按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程
2.如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
3.然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init 函数的话,则调用该函数。
4.在完成这一切之后,main 也执行同样的过程,最后调用 main 函数开始执行程序。
GO命名规范
干净、可读的代码和简洁性是Go追求的主要目标
1.名称不需要指出自己所属的包
2.返回某个对象的函数或方法的名称一般都是使用名词,没有Get。。之类的字符,如果用于修改,则使用setName,有必要的话,可以使用大小写会和的方式,如MixedCaps或mixedCaps,而不要使用下划线来分割名称