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 目录约定有三个子目录:
1.src 存放源代码(比如:.go .c .h .s等)
2.pkg 编译后生成的文件(比如:.a)
3.bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用${GOPATH//://bin:}/bin添加所有的bin目录)
GOBIN:存放Go的可执行文件的目录
PATH:为了方便使用Go语言命令和Go程序的可执行文件,需要追加:
工作区和GOPATH
工作区是放置Go源码文件的目录
一般情况下,Go源码文件都需要存放到工作区中
但是对于命令源码文件来说,这不是必须的
每一个工作区的结构大致如下:(以linux系统为例)
/home/yourusername/golib
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语言程序、代表功能:命令源码文件、库源码文件;代表辅助:测试源码文件)
命令源码文件:(1)声明自己属于main代码包,(2)包含无参数声明和结果声明的main函数
命令源码文件是Go程序的入口,但不建议吧程序都写在一个文件中
被安装之后,相应的归档文件(以.a为后缀的文件)会被存放到<当前工作区目录>/pkg/<平台相关目录>
测试源码文件:不具备命令源码文件的那两个特征的源码文件;名称以 _test.go 为后缀;
并且,该函数接收一个类型为 *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函数的执行时机如下:
好吧,来的是客,客先行。例如,代码包A调用B,B调用C,那么执行顺序是C->B->A
好,我们稍微总结一下,假如说,现在有多个代码包存在调用关系,并且,每个代码包中也存在多个init函数。
注意:我们不应该对在同一个代码包中被导入的多个代码包的init函数的执行顺序做出假设!
例如,代码包A中导入了代码包B和C,我们不能够假设出B和C哪个代码包中的init函数先执行。
所有在GO程序中被导入的代码包的init函数的执行都是在GO的程序入口即main函数之前。init先执行,main后执行。