Skip to content

语言特性

Go 语言从本质上(程序和结构方面)来实现并发编程。

因为 Go 语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同。但是它通过接口 (interface) 的概念来实现多态性。Go 语言有一个清晰易懂的轻量级类型系统,在类型之间也没有层级之说。因此可以说这是一门混合型的语言。

在传统的面向对象语言中,使用面向对象编程技术显得非常臃肿,它们总是通过复杂的模式来构建庞大的类型层级,这违背了编程语言应该提升生产力的宗旨。

函数是 Go 语言中的基本构件,它们的使用方法非常灵活。

Go 语言使用静态类型,所以它是类型安全的一门语言,加上通过构建到本地代码,程序的执行速度也非常快。

作为强类型语言,隐式的类型转换是不被允许的,记住一条原则:让所有的东西都是显式的。

Go 语言其实也有一些动态语言的特性(通过关键字 var),所以它对那些逃离 Java 和 .Net 世界而使用 Python、Ruby、PHP 和 JavaScript 的开发者们也具有很大的吸引力。

Go 语言支持交叉编译,比如说你可以在运行 Linux 系统的计算机上开发运行 Windows 下运行的应用程序。这是第一门完全支持 UTF-8 的编程语言,这不仅体现在它可以处理使用 UTF-8 编码的字符串,就连它的源码文件格式都是使用的 UTF-8 编码。Go 语言做到了真正的国际化!

环境变量

Go 开发环境依赖于一些操作系统环境变量,你最好在安装 Go 之前就已经设置好他们。目标机器是指你打算运行你的 Go 应用程序的机器。

  • $GOROOT:表示 Go 在你的电脑上的安装位置,它的值一般都是 $HOME/go,当然,你也可以安装在别的地方。

  • $GOARCH:表示目标机器的处理器架构,它的值可以是 386amd64arm

  • $GOOS:表示目标机器的操作系统,它的值可以是 darwinfreebsdlinuxwindows

  • $GOBIN:表示编译器和链接器的安装位置,默认是 $GOROOT/bin,如果你使用的是 Go 1.0.3 及以后的版本,一般情况下你可以将它的值设置为空,Go 将会使用前面提到的默认值。

  • $GOCACHE:Go 构建缓存的路径,用于存储中间构建结果以提高构建性能,默认 $HOME/.cache/go-build

  • $GOPROXY:Go 模块代理的 URL,用于下载和管理模块依赖,默认值 https://proxy.golang.org

    • 设置国内代理:
    go
    go env -w GOPROXY=https://goproxy.cn,direct
  • $GO111MODULE:Go 1.11 版本引入了模块(module)的概念,它用于管理依赖包,它的值可以是 onoffauto,默认值是 auto

Go 编译器支持交叉编译,也就是说你可以在一台机器上构建能够在不同操作系统和处理器架构上运行的应用程序,也就是说编写源代码的机器可以和目标机器有完全不同的特性(操作系统与处理器架构)。

为了区分本地机器和目标机器,你可以使用 $GOHOSTOS$GOHOSTARCH 设置本地机器的操作系统名称和编译体系结构,这两个变量只有在进行交叉编译的时候才会用到,如果你不进行显示设置,他们的值会和本地机器($GOOS$GOARCH)一样。

  • $GOPATH:默认采用和 $GOROOT 一样的值,但从 Go 1.1 版本开始,你必须修改为其它路径。它可以包含多个 Go 语言源码文件、包文件和可执行文件的路径,而这些路径下又必须分别包含三个规定的目录:srcpkgbin,这三个目录分别用于存放源码文件、包文件和可执行文件。
  • $GOARM:专门针对基于 arm 架构的处理器,它的值可以是 5 或 6,默认为 6。
  • $GOMAXPROCS:用于设置应用程序可使用的处理器个数与核数。

程序的一般结构

Go 程序的执行(程序启动)顺序如下:

  1. 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
  2. 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
  3. 然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init() 函数的话,则调用该函数。
  4. 在完成这一切之后,main 也执行同样的过程,最后调用 main() 函数开始执行程序。

命名规范

干净、可读的代码和简洁性是 Go 追求的主要目标。通过 gofmt 来强制实现统一的代码风格。Go 语言中对象的命名也应该是简洁且有意义的。像 Java 和 Python 中那样使用混合着大小写和下划线的冗长的名称会严重降低代码的可读性。名称不需要指出自己所属的包,因为在调用的时候会使用包名作为限定符。返回某个对象的函数或方法的名称一般都是使用名词,没有 Get... 之类的字符,如果是用于修改某个对象,则使用 SetName()。有必须要的话可以使用大小写混合的方式,如 MixedCaps()mixedCaps(),而不是使用下划线来分割多个名称。

注释

单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。

多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾,且不可以嵌套使用,多行注释一般用于包的文档描述或注释成块的代码片段。

每一个包应该有相关注释,在 package 语句之前的块注释将被默认认为是这个包的文档说明,其中应该提供一些相关信息并对整体功能做简要的介绍。

几乎所有全局作用域的类型、常量、变量、函数和被导出的对象都应该有一个合理的注释,称为文档注释。

godoc 工具会收集这些注释并产生一个技术文档。