初始Go语言

为何要学Go

编程语言已经非常多,偏性能敏感的编译型语言有 C、C++、Java、C#、Delphi和Objective-C 等,偏快速业务开发的动态解析型语言有PHP、Python、Perl、Ruby、JavaScript和Lua等,面向特 定领域的语言有Erlang、R和MATLAB等,那么我们为什么需要 Go这样一门新语言呢?

在2000年前的单机时代,C语言是编程之王。随着机器性能的提升、软件规模与复杂度的提 高,Java逐步取代了C的位置。

尽管看起来Java已经深获人心,但Java编程的体验并未尽如人意。

bilibili技术总监毛剑做为golang专家也说过,再诸多选择面前,自己如何能脱颖而出,因此是go,而不是java。

Go语言官方自称,之所以开发Go 语言,是因为“近10年来开发程序之难让我们有点沮丧”。

这一定位暗示了Go语言希望取代C和Java的地位,成为最流行的通用开发语言。

Go希望成为互联网时代的C语言。

并发与分布式

多核化和集群化是互联网时代的典型特征,那语言需要哪些特性来应对这些特征呢?

第一个话题是并发执行的“执行体”。

执行体是个抽象的概念,在操作系统层面有多个概念 与之对应,比如操作系统自己掌管的进程(process)、进程内的线程(thread)以及进程内的协程 (coroutine,也叫轻量级线程)。

多数语言在语法层面并不直接支持协程,而通过库的方式支持的 协程的功能也并不完整,比如仅仅提供协程的创建、销毁与切换等能力。

如果在这样的协程中调 用一个同步IO操作,比如网络通信、本地文件读写,都会阻塞其他的并发执行协程,从而无法真

正达到协程本身期望达到的目标。

Go语言在语言级别支持协程,叫goroutine。

Go语言标准库提供的所有系统调用(syscall)操作,当然也包括所有同步IO操作,都会出让CPU给其他goroutine,这让事情变得非常简单。

追求性能与效率并存

最近十年来,C/C++在计算领域没有很好得到发展,并没有新的系统编程语言出现。

对开发程度和系统效率在很多情况下不能兼得。要么执行效率高,但低效的开发和编译,如C++;

要么执行低效,但拥有有效的编译,如.NET、Java;所以需要一种拥有较高效的执行速度、编译速度和开发速度的编程语言,Go就横空出世了。

传统的语言比如c++,大家花费太多时间来学习如何使用这门语言,而不是如何更好的表达写作者的思想,同时编译花费的时间实在太长,对于编写-编译-运行这个链条来说周期太长。

动态语言如Python,由于没有强类型的约束,很多问题需要在运行时发现,这种低级错误更应该交给编译器来发现。

简单总结如下原因

  • 人力成本越来越高
  • 机器越来越便宜
  • 机器的性能越来越厉害
  • 在开发效率和运行速度上达到平衡

go出现之前,无论汇编语言、还是动态脚本语言,在执行效率和开发效率上都不能兼备。

执行效率 execution speed: C/C++ > Java > PHP 开发效率 developing efficiency: PHP > Java > C/C++

阵容豪华的创使人团队

image-20210601130737782

Ken Thompson

  • 1966年:加入了贝尔实验室,在参与 Multics (多路信息计算)开发期间,创造出了B语言,并用一个月的时间用B语言开发了全新的操作系统UNICS,后来改名为我们所熟悉的UNIX 操作系统。
  • 1971年:和丹尼斯·利奇(Dennis Ritchie)一起共同发明了C语言。
  • 1973年:和丹尼斯·利奇(Dennis Ritchie)使用C语言重写了UNIX,并安装于PDP-11的机器之上。
  • 1983年:美国计算机协会将图灵奖授予汤普森。
  • 2000年:离开贝尔实验室,已退休的汤普森成为了一名飞行员。
  • 2006年:加入Google工作。
  • 2007年:64岁的高龄,与Rob Pike和Robert Griesemer主导了Go语言的开发。

Rob Pike

  • Go语言项目总负责人。
  • 贝尔实验室Unix团队成员,参与的项目包括Plan 9,Inferno操作系统和Limbo编程语言。
  • UTF-8字符集规范唯二的发明人之一(另一位是Ken Thompson)。
  • 《UNIX环境编程》和《程序设计实践》这两本书的作者之一。
  • 第22届莫斯科夏季奥运会射箭项目的银牌得主。
  • 业余天文学家,设计的珈玛射线望远镜差点被 NASA 用在航天飞机上。
  • 他的媳妇Renee French 就是 Go 语言吉祥物的设计人。

Robert Griesemer

  • 参与V8 JavaScript引擎的开发。
  • 参与Java HotSpot虚拟机的研发。

Golang起源

2007年,Google的几位大牛正在用C++开发一些比较繁琐但是核心的工作,主要是分布式集群,大牛觉得很闹心。

此时C++委员会来他们公司做技术演讲,说C++将要添加35个新特性,大牛心里飘过一万个CNM,“C++特性还不够多吗”。

于是Rob Pike说要不自己搞个简单一点的语言吧,首先名字得简单好记,大腿一拍就叫“go”。

把事情搞复杂很容易,把事情搞简单才更深刻。

img

这是一封由 Rob Pike 在 2007 年 9 月 25 号,星期二,下午 3:12 回复给 Robert Griesemer、Ken Thompson 的有关编程语言讨论主题的邮件,邮件正文大意为:

  • 在开车回家的路上我得到了些灵感。

  • 给这门编程语言取名为“go”,它很简短,易书写。工具类可以命名为:goc、 gol、goa。

  • 交互式的调试工具也可以直接命名为“go”。

  • 语言文件后缀名为 .go 等等

这就是 Go 语言名字的来源,自此之后 Robert、Rob 和 Ken 三个人开始在 Google 内部进行了研发,一直到了 2009 年,Go 正式开源了,Go 项目团队将 2009 年 11 月 10 日,即该语言正式对外开源的日字作为其官方生日。

Golang发展

  • 2007年9月21日,开始雏形设计。
  • 2009年10月30日,Rob Pike宣布了Go语言的存在。
  • 2009年11月10日,以完全开源的方式公布了Linux和Mac OSX上的版本,11月22日公布了Windows版本。
  • 2010年1月8日,当选2009年年度语言。
  • 2010年5月,谷歌投入使用。
  • 2011年4月,谷歌开始抽调员工全职开发Go语言,并于5月宣布Google APP Engine支持Go语言。

Go语言 是Google公司 在2007开发一种静态强类型、编译型语言,并在 2009 年正式对外发布。

Go语言以其近C的执行性能和近解析型语言的开发效率,以及近乎于完美的编译速度,已经风靡全球。很多人将Go语言称为21世纪的C语言,因为Go不仅拥有C的简洁和性能,而且针对多处理器系统应用程序的编程进行了优化,很好的提供了21世纪互联网环境下服务端开发的各种实用特性。

clipart2934035

Go和运维

除了大名鼎鼎的Docker,完全用GO实现,业界最为火爆的容器编排管理系统kubernetes完全用GO实现。之后的Docker Swarm,完全用GO实现。

除此之外,还有各种有名的项目,如etcd/consul/flannel,七牛云存储等等均使用GO实现。

除了云项目外,还有像今日头条、UBER这样的公司,他们也使用GO语言对自己的业务进行了彻底的重构。

云计算架构的发展,万物上云逐步成为互联网企业的标准基础设施,业务敏捷性,降本增效是是云架构的重要驱动因素。

Go开发的应用

  • 服务端系统开发,日志处理,文件系统,监控系统。
  • 云原生系统,Docker,k8s,istio,Prometheus
  • 分布式存储系统,etcd,TIDB,Influxdb
  • Web开发,如Gin,beego,net/http内置包。
  • 爬虫开发,Go强悍的并发特性,适合爬虫等大数据数据。

Go发展前景

国内外,GO都较为火热,需求不断扩大,国内一线城市更是需求较大,公司加多,不用躲过举例。

一线城市Go开发工资平均在25k+;

image-20230116180654101

Go开发环境搭建

官网https://go.dev/

https://studygolang.com/dl 建议下载地址

macos安装

➜  ~ go version
go version go1.19.4 darwin/amd64

➜  ~ which go
/usr/local/go/bin/go


➜  ~ cd /usr/local/go
➜  go ll
total 56
-rw-r--r--    1 root  wheel   1.3K Dec  2 02:12 CONTRIBUTING.md
-rw-r--r--    1 root  wheel   1.4K Dec  2 02:12 LICENSE
-rw-r--r--    1 root  wheel   1.3K Dec  2 02:12 PATENTS
-rw-r--r--    1 root  wheel   1.4K Dec  2 02:12 README.md
-rw-r--r--    1 root  wheel   419B Dec  2 02:12 SECURITY.md
-rw-r--r--    1 root  wheel     8B Dec  2 02:12 VERSION
drwxr-xr-x   24 root  wheel   768B Dec  2 03:05 api
drwxr-xr-x    4 root  wheel   128B Dec  2 03:07 bin
-rw-r--r--    1 root  wheel    52B Dec  2 02:12 codereview.cfg
drwxr-xr-x    6 root  wheel   192B Dec  2 03:05 doc
drwxr-xr-x    3 root  wheel    96B Dec  2 03:05 lib
drwxr-xr-x   13 root  wheel   416B Dec  2 03:05 misc
drwxr-xr-x    6 root  wheel   192B Dec  2 03:05 pkg
drwxr-xr-x   69 root  wheel   2.2K Dec  2 03:05 src
drwxr-xr-x  355 root  wheel    11K Dec  2 03:05 test


配置环境变量

export GOROOT=/usr/local/go
export GOPATH=/Users/yuchao/goCode
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
export GOPROXY=https://goproxy.cn,direct 

# 或者如下命令
go env -w GOPROXY=https://goproxy.cn,direct




检查环境
➜  ~ go env |grep -Ei 'goroot|goproxy|gopath'
GOPATH="/Users/yuchao/goCode"
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/go"


# 解释
GOPATH新版本后,作用是存放第三方库依赖
GOROOT使安装golang的目录,存放go原生命令
GOPROXY配置go第三方库加速源

# 创建如下3个目录
mkdir -p /Users/yuchao/goCode/{pkg,bin,src}

windows安装

go基础命令

go help: 查看帮助文档。  

go build: 对源代码和依赖的文件进行打包,生成可执行文件。  

go install: 编译并安装包或依赖,安装到$GOPATH/bin下。  

go get: 把依赖库添加到当前module中,如果本机之前从未下载过则先下载。

go mod init module_name   初始化一个Go项目。  

go mod module_name 通过扫描当前项目中的所有代码来添加未被记录的依赖至go.mod文件或从go.mod文件中删除不再被使用的依赖。  

go run: 编译并运行程序。  
go test: 执行测试代码。  
go tool: 执行go自带的工具。go tool pprof对cpu、内存和协程进行监控;go tool trace跟踪协程的执行过程。  
go vet: 检查代码中的静态错误。  
go fmt: 对代码文件进行格式化,如果用了IDE这个命令就不需要了。
go doc: 查看go标准库或第三方库的帮助文档。 如go doc fmt
go version: 查看go版本号。  
go env: 查看go环境信息。

go获取第三方包

# 目前最新的go 1.19.4版本,建议用go install替代go get了
➜  ~ go get  github.com/beego/bee
go: go.mod file not found in current directory or any parent directory.
    'go get' is no longer supported outside a module.
    To build and install a command, use 'go install' with a version,
    like 'go install example.com/cmd@latest'
    For more information, see https://golang.org/doc/go-get-install-deprecation
    or run 'go help get' or 'go help install'.
➜  ~



# go install下载第三方库时,存储在$GOPATH/pkg/mod下

如下安装的命令
go install  github.com/nsqio/nsq@latest


➜  goCode ls $GOPATH/pkg/mod/github.com/nsqio/
nsq@v1.2.1


# 案例2
➜  ~ go install github.com/beego/bee@latest
# 检查安装好的bee命令
➜  goCode ls $GOPATH/bin
bee

image-20221216205721026

编辑器快捷键

快捷键 作用
Ctrl + / 单行注释
Ctrl + Shift + / 多行注释
Ctrl + D 复制当前光标所在行
Ctrl + X 删除当前光标所在行
Ctrl + Alt + L 格式化代码
Ctrl + Shift + 方向键上或下 将光标所在的行进行上下移动(也可以使用 Alt+Shift+方向键上或下)
Ctrl + Alt + left/right 返回至上次浏览的位置
Ctrl + R 替换
Ctrl + F 查找文本
Ctrl + Shift + F 全局查找

第一个Go程序

Go代码文件,程序中必须指定启动函数main(),如同小汽车的点火开关。

1. 创建项目目录,任意你想保存代码的地方即可
➜  ~ mkdir goStudy
➜  ~ cd goStudy
➜  goStudy
➜  goStudy go mod init goStudy
go: creating new go.mod: module goStudy
➜  goStudy ls
go.mod
➜  goStudy pwd
/Users/yuchao/goStudy


# go mod 包管理后面再说
# go.mod文件,类似于Python的 requirements.txt ,记录当前项目用了哪些第三方库,以及使用的go版本






2.代码目录下创建main.go
package main // 声明是main包,表示当前代码可以被build为可执行程序

import "fmt" // 导入内置fmt包,格式化打印

func main() { // main函数,程序入口
    fmt.Println("Hello world!") //在终端打印字符串
}




3.运行代码
➜  goStudy go run main.go 
Hello world!
➜  goStudy 

4.编译代码
➜  goStudy go build
➜  goStudy ll
total 3760
-rw-r--r--  1 yuchao  staff    24B Dec 17 18:49 go.mod
-rwxr-xr-x  1 yuchao  staff   1.8M Dec 17 19:03 goStudy
-rw-r--r--  1 yuchao  staff    73B Dec 17 18:57 main.go

go build会以当前main.go所在的目录命名,生成二进制文件。
➜  goStudy ./goStudy 
Hello world!


5.生产下go部署流程

开发机器 > 代码仓库 > 线上机器  > go build


6. go程序的发版
一次编译,到处运行


7.交叉编译

两种源码,作用

1.编译二进制程序,程序入口

  • package首行声明是main包
  • func main(){}函数
package main // 声明是main包,表示当前代码可以被build为可执行程序

import "fmt" // 导入内置fmt包,格式化打印

func main() { // main函数,程序入口
    fmt.Println("Hello world!") //在终端打印字符串
}

2.作为导入的库

其他源码可以导入如下库函数。

package util

import "fmt"

func t1(){
    fmt.Println("xxxxxx")
}

交叉编译

默认我们go build的可执行文件都是当前操作系统可执行的文件

Go语言支持跨平台编译——在当前平台(例如Windows)下编译其他平台(例如Linux)的可执行文件。

跨平台编译参数

在windows终端CMD中输入如下环境变量设置。

SET CGO_ENABLED=0  // 禁用CGO
SET GOOS=linux/windows/darwin  // 目标平台是linux
SET GOARCH=amd64  // 目标处理器架构是amd64


如果你的Windows使用的是PowerShell终端,那么设置环境变量的语法为

$ENV:CGO_ENABLED=0
$ENV:GOOS="linux"
$ENV:GOARCH="amd64"


设置完毕后
go build 生成的可执行文件,就不是win默认的exe,而是如linux的文件。

Go语言特性

Go程序执行流程

对源代码编译成二进制后运行

.go代码源文件    >    go build    >    可执行文件(.exe或linux二进制命令)    >    运行结果

对源代码直接运行

.go代码文件        >    go run         >    结果
源代码                编译且运行(不会生成二进制命令)

二者区别

1.使用go build编译生成的二进制的程序,可以直接放在同类系统上直接运行,无须go开发环境
2.go run运行代码,在另一台及其上,仍然需要go开发环境,否则无法运行
3.go build,编译器会对程序依赖的库文件打包在可执行文件中,因此可执行文件体积稍大
4.windows环境go build生成的二进制命令文件,名字以.exe结尾
5.Linux环境go build 生成一个同名的二进制命令

Go语言注意事项

1.Go代码都是以.go后缀
2.Go代码的执行入口函数是main()函数
3.Go语言严格区分大小写
4.Go代码语句结尾不需要分号,编译器自动识别
5.Go代码按行进行编译,一行尽量只写一条语句
6.Go语言的简洁性使得代码中不得含有未使用的变量,以及未使用的包
7.Go语言通过大括号控制代码
8.使用go fmt 统一代码风格

Go语言的转义字符(escape char)

\t    一个制表符,代表一次tab
\n    换行符
\\    转义代表 \
\"    转义代表 "
\r    一个回车,从当前行的最前面开始输出,会覆盖以前的内容,常配合\r\n换行使用

Go语言注释

代码注释是用于解释程序的文字,注释可以提高代码可读性

//        行注释
// 本行已被注释

/* */块注释

/* 本段落被注释
本段落被注释*/

对于行注释和快注释,被注释的内容不会被Go编译器执行
注意: 块注释中不得嵌套块注释

Golang官方标准API文档

https://golang.org/pkg

1) API (Application Programming Interface,应用程序编程接口)是 Golang 提供的基本编程接口。
2) Go 语言提供了大量的标准库,因此 google 公司 也为这些标准库提供了相应的 API 文档,用于告 诉开发者如何使用这些标准库,以及标准库包含的方法。
3) Golang 中文网 在线标准库文档: https://studygolang.com/pkgdoc

Go语言命名

编码:源码文件必须是 UTF-8 格式,否则会导致编译器出错。
命名:采用 camelCasing 风格(驼峰命名法),不建议使用下划线。

Copyright © www.yuchaoit.cn 2025 all right reserved,powered by Gitbook作者:于超 2023-01-17 14:52:15

results matching ""

    No results matching ""