把屎把尿带你Go系列(一)——Go语言开天之路
Go语言的三大特点: 1.静态类型、编译型的开源语言。静态+编译,这两个特点就标志着go语言对程序运行速度的追求。(当然大大高于 动态类型、解释型编程语言) 2.脚本化的语法;支持多种编程范式(支持 函数式编程 和 面向对象编程) 3.原生的、强大的并发编程支持。 go语言的语法里面本身存在某种方式或者方法,能够把一些代码片段,并发地提交给CPU执行。值得注意的是,原生的支持 和 通过(第三方)函数库支持是有明显的区别的。 这意味着两个advantages: 这就意味了利用go语言能够更容易地开发出并发程序,降低了开发成本和维护成本 并发程序得益于go语言实现内部的调度算法,并发程序能够更好地执行。 但是,缺点,你懂的: 1. go语言的语法糖没有python和ruby那么多,但是本人觉得完全可以接受。 2. go语言的运行效率现在还不及c,但是已经超过了C++和Java。(打住,我不想变成语言帝,也不想和人撕B)。并且,从go1.5开始,google开始用go语言来重构go编译器,因此,在编译速度上1.5的编译速度要大大低于用c语言实现的前一代(即go1.4)版本编译器编译效率。虽然在后续go1.6版本有所提升,但是与1.4的编译效率还是存在差距。不过,听说1.7的编译效率会大大提升,也许go这种彻底脱离c的努力就快得到回报了吧。 (此处参考文章:http://www.infoq.com/cn/news/2016/04/go-17-toolchain-improvements) 3. go语言的第三方库不及java和python Golang的安装: 记得go语言刚诞生那会儿,系统还不支持windows,现在倒是win、linux、unix通吃。 下载的时候,如果你在国外,就上官网下;如果在国内,就请“佛跳墙”下载,咳咳。。。 好吧,这里给个国内的下载站:http://www.golangtc.com/download 记得选择正确的系统版本和机器位数版本,我这里在64位windows上做个示范,选择go1.6.2.windows-amd64.msi 安装完之后,配置环境变量: GOROOT:go语言安装包的安装目录 GOPATH:go语言工作区的集合 $GOPATH 目录约定有三个子目录: GOBIN:存放Go的可执行文件的目录 PATH:为了方便使用Go语言命令和Go程序的可执行文件,需要追加: 工作区和GOPATH 工作区是放置Go源码文件的目录 一般情况下,Go源码文件都需要存放到工作区中 但是对于命令源码文件来说,这不是必须的 每一个工作区的结构大致如下:(以linux系统为例) /home/yourusername/golib src/ 用于存放源码文件;以代码包为组织形式 pkg/ 用于存放归档文件(归档文件就是名称以.a为后缀的文件);所有归档文件都会被存放到该目录下的平台相关目录中,同样以代码包为组织形式。平台相关目录,指的是两个隐藏的GO语言环境变量GOOS和GOARC GOOS:GO语言安装目标的操作系统 GOARCH:GO语言安装到环境的计算架构 平台相关目录以$GOOS_$GOARCH为命名方式,如:linux_amd64 所有我们编译之后或者说安装之后的函数库或者代码包都被安装在 <工作区目录>/pkg/<平台相关目录>/<一级代码包>/<二级代码包>/.../<末级代码包>.a bin/ 用于存放当前工作区中的Go程序可执行文件,与$GOBIN其实有相似的作用。 但是,请注意: (1) 当环境变量GOBIN已经有效设置时,该目录会变的无意义 (2) 当GOPATH的值中包含多个工作区的路径时,必须设置GOBIN,否则无法成功安装GO程序的可执行文件 源码文件的分类和含义 Go源码文件:名称以.go为后缀,内容以Go语言代码组织的文件 多个Go源码文件是需要用代码包组织起来的 源码文件分为三类:(go语言程序、代表功能:命令源码文件、库源码文件;代表辅助:测试源码文件) 命令源码文件:(1)声明自己属于main代码包,(2)包含无参数声明和结果声明的main函数 命令源码文件是Go程序的入口,但不建议吧程序都写在一个文件中 注意:同一个代码包中强烈不建议直接包含多个命令源码文件 库源码文件:不具备命令源码文件的那两个特征的源码文件 被安装之后,相应的归档文件(以.a为后缀的文件)会被存放到<当前工作区目录>/pkg/<平台相关目录> 测试源码文件:不具备命令源码文件的那两个特征的源码文件;名称以 _test.go 为后缀; 其中至少有一个函数名称以Test或Benchmark为前缀 并且,该函数接收一个类型为 *testing.T (指针类型)或 *testing.B (指针类型)的参数 分类: 功能测试函数 func TestFind(t *testing.T){ //省略若干条语句 } 基准测试函数(或 性能测试函数) func BenchmarkFind(b *testing.B){ //省略若干条语句 } 代码包相关概念 代码包的作用: 编译和归档GO程序的基本单位 代码包是代码划分、集结和依赖的有效组织形式,也是权限控制的辅助手段 代码包的规则: 一个代码包实际上就是一个由导入路径代表的目录 导入路径:即 <工作区目录>/src 或<工作区目录>/pkg/<平台相关目录> 之下的某段子路径。 例如,现在有代码包happyBKs.cn,其可以相当于 /home/neil/golib/src/happyBKs.cn 目录 (其中,/home/happyBKs/golib 是一个工作区目录) 代码包声明: 每个源码文件必须声明其所属的代码包 同一个代码包中的所有源码文件声明的代码包应该是相同的 代码包声明与代码包导入路径的区别:代码包声明语句中的包名称应该是代码包的导入路径的最右子路径。例如,存在代码包happyBKs.cn/pkgtool ,源码文件属于该代码包下面,那么源码文件中代码包声明语句就可以写为 package pkgtool 这样的一个好处就是,如果我们把pkgtool迁移到其他代码包下,可以不用修改源码文件中的代码包声明语句。 代码包的导入:代码包导入语句中使用的包名称应该与其导入路径一致,例如: 例如,有三个代码包:flag、fmt、strings 那么,代码包导入语句应该写为: import( "flag" "fmt" "string" ) 其他几点导入注意事项: 1. 带别名导入:相当于给代码包起个别名,如我们给代码包strings起个别名叫str import str "strings" 那么,我们就可以将调用写法由: strings.HasPrefix("xyz","x") 写为: str.HasPrefix("xyz","x") 2. 本地化导入 如果我们在源码中写了 import "strings" 那么,调用时相应的代码包可以不写 HasPrefix("xyz","x") 这个跟Java导入包差不多,不再累述 3. 仅仅初始化:这是一种非常另类的导入方式 import_ "strings" 我们导入了这个代码包,但是我们并不想调用其中的任何程序实体。也就是说,这种导入包的方式仅仅执行代码包中的初始化函数。(仅仅执行初始化代码包的动作,没法在源码文件中调用代码包中的任何实体。) 代码包初始化函数:即无参数声明和结果声明的init函数 init函数可以被声明在任何文件中,且可以有多个 init函数的执行时机(或者说顺序)——单一代码包内 注意:同一个代码包内,所有init的执行顺序是不确定的! init函数的执行时机(或者说顺序)——不同代码包之间 如果当前代码包和其导入的代码包中都有init函数,那么这些事init函数的执行时机如下: 好吧,来的是客,客先行。例如,代码包A调用B,B调用C,那么执行顺序是C->B->A 好,我们稍微总结一下,假如说,现在有多个代码包存在调用关系,并且,每个代码包中也存在多个init函数。 注意:我们不应该对在同一个代码包中被导入的多个代码包的init函数的执行顺序做出假设! 例如,代码包A中导入了代码包B和C,我们不能够假设出B和C哪个代码包中的init函数先执行。 所有在GO程序中被导入的代码包的init函数的执行都是在GO的程序入口即main函数之前。init先执行,main后执行。 无论有多少个代码包,每个代码包中有多少个init函数,每个init函数只会被执行一次。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |