Go语言的前世今生

一、 为什么需要一个新的语言

          最近十年来,C/C++在计算领域没有很好得到发展,并没有新的系统编程语言出现。对开发程度和系统效率在很多情况下不能兼得。要么执行效率高,但低效的开发和编译,如C++;要么执行低效,但拥有有效的编译,如.NET、Java;所以需要一种拥有较高效的执行速度、编译速度和开发速度的编程语言,Go就横空出世了。

传统的语言比如c++,大家花费太多时间来学习如何使用这门语言,而不是如何更好的表达写作者的思想,同时编译花费的时间实在太长,对于编写-编译-运行这个链条来说周期太长。动态语言如Python,由于没有强类型的约束,很多问题需要在运行时发现,这种低级错误更应该交给编译器来发现。

  • 人力成本越来越高

  • 机器越来越便宜

  • 机器的性能越来越厉害

  • 在开发效率和运行速度上达到平衡

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的主要贡献者。

  • GO语言系列之 初识go语言_golang此外还有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 语言过程中的第一个重大惊喜是收到了以下这封邮件:

GO语言系列之 初识go语言_Go之路_02这是一封由 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 是容器语言,这是另一个完全出乎意料的结果。

GO语言系列之 初识go语言_golang_03 除了大名鼎鼎的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/

GO语言系列之 初识go语言_编程语言_04

下载完成之后双击打开,然后根据提示点击下一步直至安装成功,默认编译器会安装在: C:\Go 目录。

GO语言系列之 初识go语言_Go之路_05

GO语言系列之 初识go语言_golang_06

GO语言系列之 初识go语言_go语言_07

至此编译器就安装在 C:\Go文件夹了,并且安装的过程中也把 C:\Go\bin 加入到系统的环境变量,所以在终端可以使用go version命令 。也可以安装在其他文件夹下。

1.2 配置

为了开发项目方便和规范,在编译器安装成功之后,需要做如下几项配置:

  • 配置Go代码目录结构,为了方便管理以后自己开发的Go项目代码,在自己硬盘上最好为Go先做写目录结构的处理。

GO语言系列之 初识go语言_编译器_08

D:\go\project
├── bin,用于存放编译后的可执行文件。
├── pkg,用于存放编译后的包文件。
└── src,我们以后写的go项目代码都写到这里去,在内部为每个项目创建一个文件夹。
  • 配置相关环境变量

GO语言系列之 初识go语言_编译器_09

  •  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/ 

GO语言系列之 初识go语言_编程语言_10

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编译器

https://golang.google.cn/

2.2 点击安装

GO语言系列之 初识go语言_编程语言_11

默认的安装目录:/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编译器

https://golang.google.cn/

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/

GO语言系列之 初识go语言_编程语言_12

 

 

  下载最新版的Goland或者旧版本,双击安装包运行安装程序,按照提示完成安装。然后网上搜索对应版本的破解方法完成破解(仅供学习使用)。

  激活参考:https://shimo.im/docs/dKYCkd8PrX3ckX99/read

Go语言快速上手

一、包的概念

关于包管理的总结:

  • 一个文件夹可以称为一个包。

  • 在文件夹(包)中可以创建多个文件。

  • 在同一个包下的每个为文件中必须指定 包名称且相同

重点:关于包的分类

  • main包,如果是main包,则必须写一个main函数,此函数就是项目的入口(main主函数)。 编译生成的就是一个可执行文件。

  • 非main包,用来将代码进行分类,分别放在不同的包和文件中。

GO语言系列之 初识go语言_编译器_13

GO语言系列之 初识go语言_golang_14

注意:

  • 调用其他包的功能,需要先 import 导入,然后再使用;调用自己包中的功能时,直接调用即可(无需导入)

  • 文件中的函数首字母是小写,表示此函数只能被当前包内部文件调用。首字母是大写,则意味着任何包都可以调用。

实例: 代码目录

 GO语言系列之 初识go语言_编程语言_15

  • 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管道通信

GO语言系列之 初识go语言_编程语言_16

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)

 

GO语言系列之 初识go语言_golang_17
作者:张亚飞
gitee:https://gitee.com/zhangyafeii
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。