1 go语言介绍
go全称为 Golang,是开源的编程语言,它能让构造简单、可靠且高效的软件变得非常容易。
使用过C/C++里面线程的我们应该都知道,其使用起来非常的麻烦,不仅调用麻烦,如果想要同步数据就还需要各种锁,并且一个线程需要占用数兆内存。
而go中有专门的goroutine (轻量级线程实现)解决了这个问题,一个goroutine 仅占数K内存大小,并且其有专门的channel作为goroutine之间的数据传输结构,完全没有锁的概念,使用起来更加简单。
也正是由于这个极好的特性,go语言在服务器上使用的较多。
而且最重要的是,它的语法非常简单,接近JavaScript,并且其生成的可执行文件运行效率接近C++,不仅跨平台,它还有大量的库可以让我们直接使用。
也正由于这个特性,如果有时我们想要节约开发成本,又想要写一个高效率的程序或脚本,那就可以使用go语言,python等脚本语言开发虽然快,但执行效率相比较而言真的很低。
2 环境配置
首先点击这里,去go语言官网下载go安装包:

然后选择自己合适的版本:

因为我用的windows,所以就下载的windows版本。
下载完成后,一路点击安装即可,然后打开控制台,输入go:

有输出信息则安装成功
前面说了,go语言有很多库可以让我们使用,但由于其默认的库都在外网,所以有时候下载起来会很慢,甚至根本下载不了。
这时我们就可以调整一下go的默认配置,设置国内代理,打开控制台输入:
go env -w GOPROXY=https://goproxy.cn,direct
这样我们的go语言开发环境就配置好了。
但如果用记事本码代码,有点过于原始,所以一般我们还是要下载个专业的编辑器,比如vscode,点击这里跳转。
然后你可以在桌面或任意文件夹中,新建一个go文件夹,里面新建一个main.go的文件。
当然你也可以任意取其它名字,但.go后缀不要动。

然后,在控制台中进入这个文件夹,cd命令进入,或者直接在该文件夹上面的文件路径中输入cmd,然后Enter也可。
然后输入:code .

这是vscode的命令,.代表当前目录,即用vscode打开当前目录。
打开main.go文件,这时vscode就会在软件的右下角提醒你安装所有需要的插件,全部点安装。
3 组织结构
先将下面这段代码复制进main.go文件中:
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
这时vscode大概长下面这样:

这就是一段输出Hello World字符串的代码,Ctrl+S保存后,在控制台中进入这个目录,输入 go run main.go:

是不是非常简单!
现在我们就来理一理上面这些步骤都是在干嘛,有什么作用。
- 首先是代码中第一行的
package main
和C/C++不同,go语言采用包的概念组织代码,一个包相当于C++中的一个库,类似于vector,并且我们的主函数所在的程序必须在main包里面,这是go语言的规定,这个main.go文件将是我们主函数main函数所在的文件,因此需要在最前面申明该文件中的代码为main包中的。
- 然后是第二行代码
import "fmt"
既然有申明包,那肯定就有导入包,该行代码的意思就是导入fmt包,我们将要使用该包中的东西。
fmt为官方标准库,为format的缩写,即格式化库,常用于输出输入。
- 第三行代码:
func main()
这也是与C/C++的不同之处,申明一个函数只需要在函数名前面添加func关键字即可,而main是必须要的函数名称,为程序的执行入口,这一点和C/C++相同。
- 第四行代码:
fmt.Println("Hello world")
这就是在调用fmt这个包中的Println函数打印字符串,安装好vscode相关go的插件后,当你输入fmt.,就会自动提示其拥有的函数
- 控制台命令:
go run main.go
go即为前面我们安装好的go语言安装包中的软件,run代表运行,main.go则为要运行的文件。
但每次运行都需要用源代码也着实有些麻烦了,可不可以只编译呢?
当然也是可以的,将go run main.go改为下面这个命令即可
go build main.go
事实上,run命令也是间接调用了build命令,然后执行的,即先编译,再执行。
这时你就可以在代码目录中看到编译生成的可执行文件了。
为了更加切身体验,所以下面我们来找找上面提到的软件与包,控制台中输入go env,会列出go的各种环境变量:

我们主要需要关注的是上面两个变量值,为两个本地路径。
首先来到GOROOT变量的路径下,在bin目录中我们就可以看到两个程序:

go.exe:编译运行源代码的程序,上面我们已经用过了gofmt.exe:格式化代码格式的软件
go与C++不同,它有标准的代码格式,也就是说,无论你将代码写成什么样,为源代码运行这个gofmt.exe程序,就会成为标准格式的代码。
而在vscode中,只要你按Ctrl+S进行保存,vscode就会自动为你调用这个程序,使其成为标准格式的代码,因此这个程序我们无需操心
然后是src目录中:

就可以看到go的标准库源代码,上面我们使用到的fmt也在其中。
注意,go共享代码不是像C/C++那样提供静态库或动态库,而是直接提供源代码,一个文件夹就代表go中的一个包,包里面的就是源代码。
然后来到GOPATH目录:

这个目录里面的东西就是用户自己下载的程序或包,比如bin目录中:

这里有两个exe程序,它们是当你第一次使用vscode打开go代码时,提示你安装的。
gopls.exe:提供了很多 IDE 才有的功能,例如自动补全、重构、工作空间符号搜索、代码美化和诊断分析任何兼容的编辑器前端staticcheck.exe:看名字就知道,是静态检测代码的。
这些都不用我们管,然后来到pkg目录中:

首先是两个文件夹:
- mod:存放我们下载的第三方库
- sumdb:记录使用的第三方库相关信息
4 语法速览
相比于C/C++,go的语法很少。
首先是数据类型,常用的有bool,int,float32,string,更多类型可以点击这里查看。
有了数据类型,接下来就是声明变量,主要有以下几种方式:
var age int //只声明
var ( //同时声明多个,可以这样简写
name string
name1 string
)
var age1 int = 10 //声明的同时进行初始化赋值
var ( //声明并赋值多个
name2 string = "www.kucoding.com"
name3 string = "yushi-"
)
var age2 = 20 //go可自动推断数据类型,因此可不写int,因为根据20可推断出其为int类型
var ( //声明并赋值多个,可省略类型
name4 = "www.kucoding.com"
name5 = "yushi-"
)
age3 := 30 //在声明的同时赋值,则可以用 := 代替 = ,这样就可以不写var关键字
注意其与C/C++的区别,声明变量需要添加关键字var,并且类型写在变量名的后面。
虽然看上去也挺多的,但事实上我们使用的最多的是最后一种:age3:=30,这样一看,是不是就简单多了呢?
同时注意go中每条语句后面不需要添加;,即使你添加了,gofmt.exe也会给你删掉,vscode中保存代码时,会自动调用。
还有就是,如果你复制了上面的代码到自己的程序中,可能就会看见报错:

这也是go的特色,不允许你声明不使用的变量,只要你在最后调用一下 fmt.Println就不会报错了:

小技巧:对于导入库的操作(如import “fmt”),你无需亲手操作,只要你在代码中使用到了fmt,Ctrl+S保存一下源码,就会自动为你添加,同时没有使用到的库,也会自动为你去除。
有变量就有常量,只需要将前面声明变量的关键字var改为const即可:
const age int = 10 //由于是常量,不可更改,因此必须在声明的同时进行赋值
const age1 = 20 //而go可自动推断数据类型,因此可以简写
const ( //同时定义多个常量
num1 = 0
num2 = 1
num3 = 2
)
const ( //对于有规律的赋值操作,可以使用iota变量,其默认为0,并且每增加一行,就自动加1,该语句与上面的语句等价
num4 = iota
num5
num6
)
至于运算符,就不多说了,C/C++中有的,go基本都有,可以点击这里查看go中的运算符。
然后是判断语句,与C/C++差不多:
b := 0
if b == 0 {
fmt.Println("b为0")
} else if b == 1 {
fmt.Println("b为1")
} else {
fmt.Println("b为其它值")
}
不同点在于,这里的判断语言,无需添加小括号,而且上面的语句还可以进行简化:
if b := 0; b == 0 {
fmt.Println("b为0")
} else if b == 1 {
fmt.Println("b为1")
} else {
fmt.Println("b为其它值")
}
将需要进行判断的变量写在if中,这样的好处是不污染变量环境,如这里的b变量名只在当前的if语句中有效,后面你可以继续重新声明定义b变量。
然后是switch语句,与C/C++同样类似:
b := 0
switch b {
case 0:
fmt.Println("b为0")
case 1:
fmt.Println("b为1")
case 2:
fmt.Println("b为2")
default:
fmt.Println("b为其它值")
}
不同点在于,switch后面同样不需要小括号,并且每个case最后不需要添加break,其默认只执行该case语句,如果你想要让它继续执行后面的case语句,可以添加fallthrough关键字
switch b := 0; b {
case 0:
fmt.Println("b为0")
fallthrough
case 1:
fmt.Println("b为1")
fallthrough
case 2:
fmt.Println("b为2")
default: