Go 语言出自 Ken Thompson 和 Rob Pike、Robert Griesemer 之手,他们都是计算机科学领域的重量级人物。
1) Ken Thompson
贝尔实验室 Unix 团队成员,C 语言、Unix 和 Plan 9 的创始人之一,在 20 世纪 70 年代,设计并实现了最初的 UNIX 操作系统,仅从这一点说,他对计算机科学的贡献怎么强调都不过分。他还与 Rob Pike 合作设计了 UTF-8 编码方案。
2) Rob Pike
Go 语言项目总负责人,贝尔实验室 Unix 团队成员,除帮助设计 UTF-8 外,还帮助开发了分布式多用户操作系统 Plan 9,,Inferno 操作系统和 Limbo 编程语言,并与人合著了《The Unix Programming Environment》,对 UNIX 的设计理念做了正统的阐述。
3) Robert Griesemer
就职于 Google,参与开发 Java HotSpot 虚拟机,对语言设计有深入的认识,并负责 Chrome 浏览器和 Node.js 使用的 Google V8 JavaScript 引擎的代码生成部分。
这些计算机科学领城的重量级人物设计 Go 语言的初衷是满足 Google 的需求。设计此语言花费了两年的时间,融入了整个团队多年的经验及对编程语言设计的深入认识。设计团队借鉴了 Pascal、Oberon 和C语言的设计智慧,同时让 Go 语言具备动态语言的便利性。因此,Go 语言体现了经验丰富的计算机科学家的语言设计理念,是为全球最大的互联网公司之一设计的。
Golang 由包组成。Golang 编译器将 main
包编译为可执行文件,而非共享库。main 包是应用的入口,通常被定义如下:
package main
下面看一个 hello world 的例子,在 Golang 的工作空间创建 main.go 文件。
1.1 工作空间
在Go语言中,工作空间由环境变量GOPATH定义。所有编写的代码需要在工作空间中。Go语言会在GOPATH和GOROOT的路径中搜索包。GoROOT是在安装的时候确定的安装路径。
下面来设置GOPATH,我们将 ~/workspace
加入工作空间。
# export env export GOPATH=~/workspace # go inside the workspace cd ~/workspace
1.2 HELLO WORLD!
我们在刚才的工作空间下创建 main.go
文件,代码如下:
package main import ( "fmt" ) func main(){ fmt.Println("Hello World!") }
上面的例子中,fmt 是 Go 内置的格式化 I/O 函数。
我们在Go语言中使用 import
关键字导入包,func main
是入口函数。Println 是 fmt 包中函数,用于打印 "Hello World!"。
让我们开始运行该文件。众所周知Go是编译型语言,我们在运行之前先进行编译。
go build main.go
这将会创建一个二进制运行文件main,我们现在来运行它:
> ./main # Hello World!
另一种简单的方式是使用 go run
命令:
go run main.go # Hello World!
Go中的变量类型是显式指定的。Go语言是强类型语言,这意味着在变量声明的时候会检查变量类型。变量定义如下所示:
var a int
在这个例子中,a
的初始值被设置为0
。用下面的方式可以定义并初始化变量。
var a = 1
这里的变量被编译器推断为 int。更简单的变量定义如下所示:
message := "hello world"
我们也可以在同一行声明多个变量:
var b, c int = 2, 3
3.1 NUMBER,STRING, BOOLEAN
int 的类型有 int
、int8
、int16
、int32
、int64
、unit
、unit8
、unit16
、unit 32
、unit64
、unitptr
...
String 类型使用 byte 序列存储数据,用关键字string来声明变量。
bool
关键字表示布尔类型。
Golang 也支持复数,用 conplex64
和 complex128
表示。
var a bool = true vat b int = 1 var c string = "hello world" var d float32 = 1.222 var x complex128 = cmplx.Sqrt(-5 +12i)
3.2 ARRAYS,SLICES,MAPS
Array
是同类型元素的数组。Array
在声明的时候会指定长度且不能改变。一个数组的定义如下:
var a[5] int //也有多维数组,定义如下: var multiD [2][3]int //Slices 是能随时扩容的同类型元素的序列 。Slice的声明方式如下: var b []int //这将会创建一个容量为0,长度为0的Slice。Slice也可以定义容量和长度,格式如下: numbers := make([]int, 5, 10)
这个 Slice
初始长度为 5,容量为 10。
Slice 是数组的封装,其内部实现是数组,slice 有三个元素:容量,长度和指向内部数组的指针。
Slice 的容量可以通过 append 或者 copy 函数增加。Append 函数也能在数组的末尾添加元素,在容量不足的情况下会对 slice 扩容。
numbers = append(numbers, 1, 2, 3, 4)
另一种增加 slice 容量的方式是使用 copy 函数。Copy 函数的原理是创建一个新的大容量的slice,并把原有的 slice 拷贝到新的 slice 中。
// 创建新的slice number2 := make([]int, 15) // 复制原有的slice到新的slice copy(number2, number)
我们也可以创建 slice 的子 slice。例子如下:
package main import ( "fmt" ) func main() { // 初始化slice number2 := []int{1, 2, 3, 4} fmt.Println(number2) // -> [1 2 3 4] // 创建子slice slice1 := number2[2:] fmt.Println(slice1) // -> [3 4] slice2 := number2[:3] fmt.Println(slice2) // -> [1 2 3] slice3 := number2[1:4] fmt.Println(slice3) // -> [2 3 4] }
Go 语言中的 Map 是键值对,定义如下:
var m map[string]int
m是定义的变量名,键的类型是 string,值的类型是 integers。Map中添加键值对的例子如下:
package main import ( "fmt" ) func main() { m := make(map[string]int) // 添加键值对 m["clearity"] = 2 m["simplicity"] = 3 // 打印值 fmt.Println(m["clearity"]) // -> 2 fmt.Println(m["simplicity"]) // -> 3 }
使用类型转换能够改变数据类型,例子如下:
package main import ( "fmt" ) func increment(i *int) { *i++ } func main() { a := 1.1 b := int(a) fmt.Println(b) //-> 1 }