摘要
本文内容转自网络,个人学习记录使用,请勿传播
Go
是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。
Go
是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson
主持开发,后来还加入了Ian Lance Taylor, Russ Cox
等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1
稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。
最初Go
语言的Logo
是一只可爱的土拨鼠,土拨鼠昼伏夜出的习性让它显得很有Geek
范。土拨鼠的行动其实并不敏捷,不过它繁殖能力很强,生长发育的很快。
到了 2018年,Go 语言重新制定了 Logo,消灭了土拨鼠,取而代之的是纯文字。这好像是在告诉用户 Go 语言不再是一个玩具语言,而是一个严肃的高效的正式语言。
Go 语言特色
- 简洁、快速、安全
- 并行、有趣、开源
- 内存管理、数组安全、编译迅速
Go 语言最主要的特性:
- 自动垃圾回收
- 更丰富的内置类型
- 函数多返回值
- 错误处理
- 匿名函数和闭包
- 类型和接口
- 并发编程
- 反射
- 语言交互性
Go 语言用途
Go
语言被设计成一门应用于搭载Web
服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。
对于高性能分布式系统领域而言,Go
语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。
Go 基础
Go 语言结构
Go 语言的基础组成有以下几个部分:
- 包声明
- 引入包
- 函数
- 变量
- 语句 & 表达式
- 注释
1 | // 定义了包名 |
package main
:定义了包名- 必须在源文件中非注释的第一行指明这个文件属于哪个包
- 表示一个可独立执行的程序,每个
Go
应用程序都包含一个名为main
的包
func main()
main
函数是每一个可执行程序所必须包含的- 一般来说都是在启动后第一个执行的函数
- 如果有
init
函数则会先执行该函数
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,
如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);
标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
运行
这个文件的名字是 main.go,使用下面的命令运行这个文件
1 | $ go run main.go |
编译运行
go run
指令只是用来开发调试用的,在生产环境中程序可不是这样跑的。在开发完成后,需要将程序编译成没有任何依赖的二进制可执行文件,扔到服务器上运行起来。
1 | $ go build main.go |
设置GOPATH
1 | export GOPATH=~/go |
关键字
下面列举了 Go 代码中会使用到的 25 个关键字或保留字:
break |
default |
func |
interface |
select |
---|---|---|---|---|
case |
defer |
go |
map |
struct |
chan |
else |
goto |
package |
switch |
const |
fallthrough |
if |
range |
type |
continue |
for |
import |
return |
var |
除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符:
append |
bool |
byte |
cap |
close |
complex |
---|---|---|---|---|---|
complex64 |
complex128 |
uint16 |
copy |
false |
float32 |
float64 |
imag |
int |
int8 |
int16 |
uint32 |
int32 |
int64 |
iota |
len |
make |
new |
nil |
panic |
uint64 |
print |
println |
real |
recover |
string |
true |
uint |
uint8 |
uintptr |
程序一般由关键字、常量、变量、运算符、类型和函数组成。
程序中可能会使用到这些分隔符:括号
()
,中括号[]
和大括号{}
。
程序中可能会使用到这些标点符号:
.、,、;、: 和 …
。
数据类型
布尔型
布尔型的值只可以是常量true
或者false
。一个简单的例子:var b bool = true
。
数字类型
整型int
和浮点型float32、float64
,Go
语言支持整型和浮点型数字,并且原生支持复数,其中位的运算采用补码。
字符串类型
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
派生类型:
- 指针类型(
Pointer
) - 数组类型
- 结构化类型(struct)
Channel
类型- 函数类型
- 切片类型
- 接口类型(
interface
) Map
类型
变量与常量
变量声明的三种方式
1 | //指定变量类型,声明后若不赋值,使用默认值。 |
这三种变量定义方式都是可行的,各有其优缺点。可读性最强的是第一种,写起来最方便的是第三种,第二种是介于两者之间的形式。
通常情况下:
var
的意思就是「我很重要,你要注意」:=
的意思是「我很随意,别把我当回事」var
再带上显式的类型信息是为了方便读者快速识别变量的身份。
默认值
在第一种声明变量的时候不赋初值,编译器就会自动赋予相应类型的「零值」,不同类型的零值不尽相同,比如
- 字符串的零值不是
nil
,而是空串 - 整形的零值就是
0
- 布尔类型的零值是
false
多变量声明
1 | //类型相同多个变量, 非全局变量 |
全局变量和局部变量
1 | package main |
- 如果全局变量的首字母大写,那么它就是公开的全局变量。
- 如果全局变量的首字母小写,那么它就是内部的全局变量。
- 内部的全局变量只有当前包内的代码可以访问,外面包的代码是不能看见的。
指针类型
1 | packge main |
指针变量本质上就是一个整型变量,里面存储的值是另一个变量内存的地址。*
和 &
符号都只是它的语法糖,是用来在形式上方便使用和理解指针的。* 操作符存在两次内存读写,第一次获取指针变量的值,也就是内存地址,然后再去拿这个内存地址所在的变量内容。
常量
Go 语言还提供了常量关键字 const,用于定义常量。常量可以是全局常量也可以是局部常量。你不可以修改常量,否则编译器会抱怨。常量必须初始化,因为它无法二次赋值。全局常量的大小写规则和变量是一致的。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
常量的定义格式:
1 | const identifier [type] = value |
你可以省略类型说明符 [type]
,因为编译器可以根据变量的值来推断其类型。
1 | 显式类型定义: const b string = "abc" |
多个相同类型的声明可以简写为:
1 | const c_name1, c_name2 = value1, value2 |
注意事项
- 如果在相同的代码块中,我们不可以再次对于相同名称的变量使用初始化声明,例如
a := 20
就是不被允许的,编译器会提示错误no new variables on left side of :=
- 但是
a = 20
是可以的,因为这是给相同的变量赋予一个新的值。 - 如果你在定义变量
a
之前使用它,则会得到编译错误undefined: a
。 - 如果你声明了一个局部变量却没有在相同的代码块中使用它,同样会得到编译错误
a declared and not used
- 但是全局变量是允许声明但不使用。 同一类型的多个变量可以声明在同一行
- 多变量可以在同一行进行赋值
- 如果你想要交换两个变量的值,则可以简单地使用
a, b = b, a
,两个变量的类型必须是相同 - 空白标识符
_
也被用于抛弃值,如值5
在:_, b = 5, 7
中被抛弃 _
实际上是一个只写变量,你不能得到它的值。这样做是因为Go
语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值- 并行赋值也被用于当一个函数返回多个返回值时,
val, err = Func1(var1)
基础类型大全
1 | package main |
字符串和数字转换
1 | //字符串变成数字 |
分支与循环
Go
语言的分支循环语句选择性较少,循环语句它只有for
循环,平时我们在其它语言用的while
语句、do while
语句、loop
语句它是没有的。分支语句只有if
和switch
,也没有三元操作符。
少并不是坏事,够用就行。语法糖丰富了表面上选择性多了功能强大了,但是也会增加代码的理解成本,用户需要掌握更多的知识才可以理解代码,这会提高语言的学习门槛。
if else
Go 语言没有三元操作符,这里只能使用 if 语句
1 | package main |
switch
语句
switch 有两种匹配模式
- 一种是变量值匹配
- 一种是表达式匹配
1 | package main |
for
循环
Go 语言虽然没有提供 while 和 do while 语句,不过这两个语句都可以使用 for 循环的形式来模拟。
- for 什么条件也不带的,相当于 loop {} 语句
- for 带一个条件的相当于 while 语句
- for 带三个语句的就是普通的 for 语句
1 | package main |
循环控制
Go 语言支持 continue 和 break 语句来控制循环,这两个语句和其它语言没什么特殊的区别。除此之外 Go 语言还支持 goto 语句。
计算机科学家迪杰斯特拉很讨厌 goto 语句,他的那片广为流传的论文《Goto 有害》已经家喻户晓般地为人所知,可是他已经去世这么多年了,很遗憾还是没能阻挡 goto 语句死灰复燃般地继续存在。
1 | package main |
使用for循环的例子
1 | package main |