GO语言系列之 初识go语言
Go语言的前世今生
一、 为什么需要一个新的语言
最近十年来,C/C++在计算领域没有很好得到发展,并没有新的系统编程语言出现。对开发程度和系统效率在很多情况下不能兼得。要么执行效率高,但低效的开发和编译,如C++;要么执行低效,但拥有有效的编译,如.NET、Java;所以需要一种拥有较高效的执行速度、编译速度和开发速度的编程语言,Go就横空出世了。
-
人力成本越来越高
-
机器越来越便宜
-
机器的性能越来越厉害
-
在开发效率和运行速度上达到平衡
go出现之前,无论汇编语言、还是动态脚本语言,在执行效率和开发效率上都不能兼备。
执行效率 execution speed: C/C++ > Java > PHP 开发效率 developing efficiency: PHP > Java > C/C++
二、 谷歌工程师的20%时间
谷歌的“20%时间”工作方式,允许工程师拿出20%的时间来研究自己喜欢的项目。语音服务Google Now、谷歌新闻Google News、谷歌地图Google Map上的交通信息等,全都是20%时间的产物。Go语言最开始也是20%时间的产物。
三、 创始人
Go的三个作者分别是: Rob Pike(罗伯.派克),Ken Thompson(肯.汤普森)和Robert Griesemer(罗伯特.格利茨默) 。
-
Rob Pike:曾是贝尔实验室(Bell Labs)的Unix团队,和Plan 9操作系统计划的成员。他与Thompson共事多年,并共创出广泛使用的UTF-8 字元编码。
-
Ken Thompson:主要是B语言、C语言的作者、Unix之父。1983年图灵奖(Turing Award)和1998年美国国家技术奖(National Medal of Technology)得主。他与Dennis Ritchie是Unix的原创者。Thompson也发明了后来衍生出C语言的B程序语言。
-
Robert Griesemer:在开发Go之前是Google V8、Chubby和HotSpot JVM的主要贡献者。
- 此外还有Plan 9开发者Russ Cox、和曾改善目前广泛使用之开原码编译器GCC的Ian Taylor。
四、 Go的缔造与发展
4.1 Go的命名
这是一封由 Rob Pike 在 2007 年 9 月 25 号,星期二,下午 3:12 回复给 Robert Griesemer、Ken Thompson 的有关编程语言讨论主题的邮件,邮件正文大意为:在开车回家的路上我得到了些灵感。1.给这门编程语言取名为“go”,它很简短,易书写。工具类可以命名为:goc、 gol、goa。交互式的调试工具也可以直接命名为“go”。语言文件后缀名为 .go 等等
这就是 Go 语言名字的来源,自此之后 Robert、Rob 和 Ken 三个人开始在 Google 内部进行了研发,一直到了 2009 年,Go 正式开源了,Go 项目团队将 2009 年 11 月 10 日,即该语言正式对外开源的日字作为其官方生日。源代码最初托管在 http://code.google.com 上,之后几年才逐步的迁移到 GitHub 上。
4.2 Go的发展过程中的记事
第一个事情是在开发设计 Go 语言过程中的第一个重大惊喜是收到了以下这封邮件:
这是一封由 Ian Lance Taylor 在 2008 年 6月 7 日(星期六)的晚上 7:06 写给 Robert Griesemer、Rob Pike、 Ken Thompson 的关于 Go gcc 编译器前端的邮件。邮件正文大意如下:我的同事向我推荐了这个网站 http://…/go_lang.html 。这似乎是一门很有趣的编程语言。我为它写了一个 gcc 编译器前端。虽然这个工具仍缺少很多的功能,但它确实可以编译网站上展示的那个素数筛选程序了。
Ian Lance Taylor 的加入以及第二个编译器 (gcc go) 的实现 在带来震惊的同时,也伴随着喜悦。这对 Go 项目来说不仅仅是鼓励,更是一种对可行性的证明。语言的第二次实现对制定语言规范和确定标准库的过程至关重要,同时也有助于保证其高可移植性,这也是 Go 语言承诺的一部分。自此之后 Ian Lance Taylor 成为了设计和实现 Go 语言及其工具的核心人物。
第二件事情是 Russ Cox 在2008年带着他的语言设计天赋和编程技巧加入了刚成立不久的 Go 团队。Russ 发现 Go 方法的通用性意味着函数也能拥有自己的方法,这直接促成了 http.HandlerFunc 的实现,这是一个让 Go 一下子变得无限可能的特性。Russ 还提出了更多的泛化性的想法,比如 io.Reader 和 io.Writer 接口,奠定了所有 I/O 库的整体结构。
第三件事情是聘请了安全专家 Adam Langley 帮助 Go 走向 Google 外面的世界。Adam 为 Go 团队做了许多不为外人知晓的工作,包括创建最初的 http://golang.org 网站以及 build dashboard。不过他最大的贡献当属创建了 cryptographic 库。起先,在我们中的部分人看来,这个库无论在规模还是复杂度上都不成气候。但是就是这个库在后期成为了很多重要的网络和安全软件的基础,并且成为了 Go 语言开发历史的关键组成部分。许多网络基础设施公司,比如 Cloudflare,均重度依赖 Adam 在 Go 项目上的工作,互联网也因它变得更好。我记得当初 beego 设计的时候,session 模块设计的时候也得到了 Adam 的很多建议,因此,就 Go 而言,我们由衷地感谢 Adam。
第四个事情就是一家叫做 Docker 的公司。就是使用 Go 进行项目开发,并促进了计算机领域的容器行业,进而出现了像 Kubernetes 这样的项目。现在,我们完全可以说 Go 是容器语言,这是另一个完全出乎意料的结果。
除了大名鼎鼎的Docker,完全用GO实现。业界最为火爆的容器编排管理系统kubernetes完全用GO实现。之后的Docker Swarm,完全用GO实现。除此之外,还有各种有名的项目,如etcd/consul/flannel,七牛云存储等等 均使用GO实现。有人说,GO语言之所以出名,是赶上了云时代。但为什么不能换种说法?也是GO语言促使了云的发展。
除了云项目外,还有像今日头条、UBER这样的公司,他们也使用GO语言对自己的业务进行了彻底的重构。
4.3 总结
Go语言是谷歌2009年发布的第二款开源编程语言(系统开发语言),它是基于编译、垃圾收集和并发的编程语言。 Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美 C / C++代码的速度,而且更加安全、支持并行进程。作为出现在21世纪的语言,其近C的执行性能和近解析型语言的开发效率,以及近乎于完美的编译速度,已经风靡全球。特别是在云项目中,大部分都使用了Golang来开发。不得不说,Golang早已深入人心。而对于一个没有历史负担的新项目,Golang或许就是个不二的选择。 很多人将Go语言称为21世纪的C语言,因为Go不仅拥有C的简洁和性能。而且还很好的提供了21世纪互联网环境下服务端开发的各种实用特性。被称为Go语言之父的罗勃·派克(Rob Pike)就曾说过,你是否同意Go语言,取决于你是认可少就是多,还是少就是少(Less is more or less is less)。Go语言的整个设计哲学就是:将简单、实用体现得淋漓尽致。 如今 Go 已经是云计算编程语言,GO语言背靠Google这棵大树,又不乏牛人坐镇,是名副其实的“牛二代”。想象一下:一个只有十几年发展经历的编程语言,已经成为了如此巨大而且正在不断发展的行业的主导者,这种成功是每个人都无法想象的。
五、为什么学Go?
一句话概括:天赋与背景并存,集性能和效率于一身的开发语言,有谷歌支持。
区块链和容器化时代的到来,把Go语言也带火了起来。除此之外,Go语言也被誉为 “21世纪的C语言”从性能和简洁程度也比较优秀。
Go算是编程语言届的优等生,集 Python的简洁
和 C语言的性能
于一身,让开发在保证性能的前提下更加高效。
Golang是一门编译型、适用于大型项目开发的编程语言。关于Go语言可以简单罗列他的几个特点:
- 编译型语言,写完的代码需要编译成为二进制文件再运行(默认静态编译),C语言也是需要先编译再运行(默认动态编译)。
- 并发编程,Go的并发方面比较优秀(其他语言其实也能做到,只不过Go在编译器级别而其他则更多的是用户级别了)。
- 语法简洁 & 上手快,这点和Python比较相似,写的代码少可以做的事很多。
除此之外,Go在类型和异常等细节方面,让他在编写大型项目时更加占优势。
初识Go语言
一、golang语言的特性
1.垃圾回收
- a.内存自动回收,再也不需要开发人员管理内存
- b.开发人员专注业务实现,降低了心智负担
- c.只需要new分配内存,不需要释放
2.天然并发
- a.从语言层面支持并发,非常简单
- b.goroute,轻量级线程,创建成千上万个goroute成为可能
- c.基于CSP(Commnuncating Sequential Process)模型并发
func main() { go fmt.Println(“hello") }
3.channel
- a.管道,类似unix/linux中的pipe
- b.多个goroute之间通过channel进行通信
- c.支持任何类型
func test_pipe() { pipe := make(chan int, 3) pipe <- 1 pipe <- 2 pipe <- 3 sum = <-pipe // pipe <- 4 fmt.Println("sum=", sum) fmt.Println(len(pipe)) }
二、开发环境搭建
Go 和 C语言、C++、Python、Java 等一样都是编程语言。学习任何一门编程语言本质上都分3步走:
-
第一步:安装
解释器 或 编译器
。 -
第二步:学相关编程语言语法,然后写代码。
-
第三步:用已安装
解释器 或 编译器
去运行自己写的代码,这样代码就会去完成我们编写的功能了。
Go是编译型语言,所以我们一般称Go安装是编译器
。
Go是开源且跨平台的一门编程语言,所以他支持window、linux、mac操作系统,同时也意味着我们可以在各种系统中安装Go的编译器。
Go 语言支持以下系统:
-
Linux
-
FreeBSD
-
Mac OS X(也称为 Darwin)
-
Windows
1. Windows系统
1.1 下载安装
去官网下载安装包,地址:https://golang.google.cn/dl/
下载完成之后双击打开,然后根据提示点击下一步直至安装成功,默认编译器会安装在: C:\Go
目录。
至此编译器就安装在 C:\Go
文件夹了,并且安装的过程中也把 C:\Go\bin
加入到系统的环境变量,所以在终端可以使用go version命令 。也可以安装在其他文件夹下。
1.2 配置
为了开发项目方便和规范,在编译器安装成功之后,需要做如下几项配置:
- 配置Go代码目录结构,为了方便管理以后自己开发的Go项目代码,在自己硬盘上最好为Go先做写目录结构的处理。
D:\go\project ├── bin,用于存放编译后的可执行文件。 ├── pkg,用于存放编译后的包文件。 └── src,我们以后写的go项目代码都写到这里去,在内部为每个项目创建一个文件夹。
-
配置相关环境变量
- GOROOT
GOROOT为GO的安装目录,比如C:/GO,GOROOT/bin
下包含Go为我们提供的工具链,因此应该将GOROOT/bin
配置到环境变量PATH中,方便我们在全局中使用Go的工具链。使得可以在命令中直接使用Go相关命令。
- GOPATH
GOPATH为Go的工作目录,通常至少包含bin、pkg个src三个目录
-
- bin:主要存放可执行文件。
- pkg:存放编译好的库文件, 主要是*.a文件。现在主要存放go mod模式中下载的包文件
- src:下主要存放go的源文件。
此外还需要注意的是不要讲GOROOT设置城Go语言的路径,避免出现不必要的冲突。
- GOBIN
GOBIN是我们在开发程序编译后二进制命令的安装目录。当我们使用go install命令编译和打包应用程序时,该命令会将编译后的二进制程序打包GOBIN目录,一般我们将GOBIN设置为GOPATH/bin。
- GOPROXY
GOPROXY为GO下载包时的代理设置。对于golang 语言的开发,对于国内来说有点被动,需要想各种方法,一般的解决方法如下:
-
- 使用代理工具(FQ)
- 配置goproxy
阿里云 https://mirrors.aliyun.com/goproxy/ 七牛云 https://goproxy.cn goproxy.io https://goproxy.io/
1.3 写代码
在 GOPATH 下的 src 目录中创建一个 文件夹(项目)
,进入文件夹并创建一个以.go
为后缀名的文件(如 first.go),并在first.go文件中写入go代码(可先用记事本编写)。
D:\go\project ├── bin ├── pkg └── src └── day01,项目 └── first.go,项目中的文件
// first.go 文件中的代码内容如下 package main import "fmt" func main() { // 调用Println函数在屏幕输出:叫爸爸 fmt.Println("叫爸爸") }
1.4 执行代码
编译器安装完成并且代码也写好之后,就可以使用Go编译器去运行代码了。
Go编译器提供了3种方式让我们来运行自己编写的go程序代码。
-
方式一:
go run
,compile and run Go program ,其内部会【先编译】代码文件【再运行】(二合一)。 -
方式二:
go build
,compile packages and dependencies,其内部就是将go代码进行编译,然后手动执行。
- 方式三:
go install
,compile and install packages and dependencies,其内部就是编译go代码,并将可执行文件/包文件分别放到 bin 和 pkg目录。
至此,Windows系统上进行Go编译器的安装就完成了。
2. Mac系统
2.1 下载Go编译器
2.2 点击安装
默认的安装目录:/usr/local/go/
编译器启动文件:/usr/local/go/bin/go
2.3 配置环境PATH
export PATH=/usr/local/go/bin:$PATH
2.4 其他配置
-
2.4.1 创建一个任意目录
此目录以后放你写的所有go代码。
/Users/xxx/GolangProjects/ - bin,通过go install编译时候,生成的可执行文件。 - pkg,通过go install编译时候,生成的包文件。 - src,放我们以后编写的所有go代码和依赖。
-
2.4.2 配置环境变量
// Go安装目录 export GOROOT=/usr/local/go // 代码和编译之后的文件相关代码 export GOPATH=/Users/xxx/GolangProjects // 存放编译之后的文件 export GOBIN=/Users/xxx/GolangProjects/bin
2.5 环境变量“持久化”
- vim ~/.bash_profile
export PATH=/usr/local/go/bin:$PATH export GOROOT=/usr/local/go export GOPATH=/Users/xxx/GolangProjects export GOBIN=/Users/xxx/GolangProjects/bin
2.6 编写go代码
$GOPATH ├── bin ├── pkg └── src └── crm └── app.go
package main import "fmt" func main() { fmt.Println("我的第一个Golang程序,好开心!") }
2.7 运行
本质上就是让Go编译器去运行咱们编写的代码。
方式1:
// 先进入项目目录 go run app.go
方式2(推荐):
// 先进入项目目录 // 编译代码 go build // 运行 ./crm
方式3:
// 先进入项目目录 go install // 去bin运行 ./crm $GOPATH ├── bin │ └── crm ├── pkg └── src └── crm └── app.go
3. Linux系统
3.1 下载Go编译器
wget -c https://studygolang.com/dl/golang/go1.14.2.linux-amd64.tar.gz tar -zxvf go1.14.2.linux-amd64.tar.gz -C /opt/go
3.2 安装
安装目录 /opt/go
启动Go编译器文件:/opt/go/bin/go
3.3 配置环境变量PATH
export PATH=/opt/go/bin:$PATH
3.4 其他配置
-
3.4.1 创建一个任意目录
存放咱们编写的所有项目代码,编译文件之后存放编译后的文件。
/home/xxx/GolangProjects/ - bin,在执行go install 命令,生成的可执行文件的目录。 - pkg,在执行go install 命令,存放生成的包文件。 - src,以后编写的所有Go代码都会放在这个目录。 - crm - app.go - luffy - lk.go
-
3.4.2 环境变量的配置
export GOROOT=/opt/go export GOPATH=/home/xxx/GolangProjects export GOBIN=/home/xxx/GolangProjects/bin
3.5 环境变量的“持久化”
vim ~/.bash_profile
export PATH=/opt/go/bin:$PATH export GOROOT=/opt/go export GOPATH=/home/xxx/GolangProjects export GOBIN=/home/xxx/GolangProjects/bin
3.6 编写go代码
/home/xxx/GolangProjects(简写$GOPATH) ├── bin ├── pkg └── src └── crm └── app.go
package main import "fmt" func main() { // 调用Println函数在屏幕输出:这是我的第一个Golang程序,好开心 fmt.Println("我的第一个Golang程序,好开心!") }
3.7 运行代码
本质上将写好的代码交给Go编译器去执行。
方式1:
// 进入项目目录 go run app.go
方式2(推荐):
// 进入项目目录 // 编译代码并生成一个可执行文件 go build // 运行 ./crm
方式3:
// 进入项目目录 // 编译代码,把编译之后的结果会放在 bin/pkg目录 go install // 运行 ./crm ├── bin │ └── crm ├── pkg └── src └── crm └── app.go
Go程序员的项目:
-
产出一个可执行文件。
-
产出一个包文件。
三、第一个golang程序
hello world, 在gopath路径下新建src目录,新建文件hello.go
package main import "fmt" func main() { fmt.Println("hello world") }
在终端输入go run hello.go,如何成功打印hello world则证明配置成功
四.、搭建Goland(推荐)
进入Goland官网:https://www.jetbrains.com/zh-cn/go/download/
下载最新版的Goland或者旧版本,双击安装包运行安装程序,按照提示完成安装。然后网上搜索对应版本的破解方法完成破解(仅供学习使用)。
激活参考:
Go语言快速上手
一、包的概念
关于包管理的总结:
-
一个文件夹可以称为一个包。
-
在文件夹(包)中可以创建多个文件。
-
重点:关于包的分类
-
main包,如果是main包,则必须写一个main函数,此函数就是项目的入口(main主函数)。 编译生成的就是一个可执行文件。
-
非main包,用来将代码进行分类,分别放在不同的包和文件中。
注意:
-
调用其他包的功能,需要先 import 导入,然后再使用;调用自己包中的功能时,直接调用即可(无需导入)
-
文件中的函数首字母是小写,表示此函数只能被当前包内部文件调用。首字母是大写,则意味着任何包都可以调用。
实例: 代码目录
- add.go
package calc func Add(a int, b int) int { return a + b }
- sub.go
package calc func Sub(a int, b int) int { return a - b }
- main.go
package main import ( "fmt" "go_dev/day1/package_example/calc" ) func main() { sum := calc.Add(100, 300) sub := calc.Sub(100, 300) fmt.Println("sum=", sum) fmt.Println("sub=", sub) }
编译
go build -o 输出路径(相对于GOPATH) 包的路径(相对于GOPATH/src) go build -o bin/calc.exe go_dev/day1/package_example/main
二、goroutine
1. goroutine实现并发
goroute.go
package main import "fmt" func test_goroute(a int) { fmt.Println(a) }
main.go
package main import "time" func main() { for i := 0; i < 100; i++ { go test_goroute(i) } time.Sleep(3 * time.Second) } // go build go_dev/day1/goroute
2. goroutine管道通信
add.go
package goroute func Add(a int, b int, c chan int) { sum := a + b c <- sum }
main.go
package main import ( "fmt" "go_dev/day1/goroute_example/goroute" ) func main() { var pipe chan int pipe = make(chan int, 1) go goroute.Add(100, 300, pipe) sum := <-pipe fmt.Println("sum=", sum)