mirror of
https://gitee.com/shikong-sk/golang-study
synced 2025-02-23 23:42:15 +08:00
766 lines
30 KiB
Markdown
766 lines
30 KiB
Markdown
|
**目录一览:**
|
|||
|
|
|||
|
- 0x00 前言简述
|
|||
|
|
|||
|
- - What,什么是Go语言?
|
|||
|
- Why,为啥要用Go语言?
|
|||
|
- How,Go语言发展前景?
|
|||
|
|
|||
|
- 0x01 Go语言开发环境搭建
|
|||
|
|
|||
|
- - Hello World
|
|||
|
- Http Web Server
|
|||
|
- Echo 类似命令程序
|
|||
|
- (1) Ubuntu桌面版
|
|||
|
- (2) 开发编辑器
|
|||
|
- 版本平台
|
|||
|
- 开发环境
|
|||
|
- Let,Go
|
|||
|
|
|||
|
- 0x02 Go 项目结构
|
|||
|
|
|||
|
- - (1)适合个人开发者
|
|||
|
- (2)适合企业开发场景
|
|||
|
- (3)目前流行的项目结构
|
|||
|
|
|||
|
|
|||
|
|
|||
|

|
|||
|
|
|||
|
# 0x00 前言简述
|
|||
|
|
|||
|
**为什么你应该学习Go语言?**
|
|||
|
|
|||
|
> 世界上已经有太多太多的编程语言了,为什么又出来一个Go语言?
|
|||
|
> 因为其编程语言的良好特性和Google公司强势推广以及以Go语言相关开源项目火爆, 比如 `etcd、kubernetes、Prometheus` 等项目, 其次是硬件性能提高则我们需要高性能的软件
|
|||
|
|
|||
|
- 1.参考 Golang 编程语言排行榜 : https://www.tiobe.com/tiobe-index
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- 2.硬件限制(摩尔定律)已然失效
|
|||
|
|
|||
|
> 摩尔定律:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会增加一倍,性能也将提升一倍。 换言之,每一美元所能买到的电脑性能,将每隔18-24个月翻一倍以上。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
从上面的图表可以看出,近十年单线程性能和处理器频率保持稳定。我们不能像之前一样把添加更多晶体管当成是解决方案,因为在较小规模上一些量子特性开始出现(如隧道效应),并且因为在同样小的空间里放置更多晶体管的代价非常昂贵,每1美元可以添加的晶体管数量开始下降。
|
|||
|
|
|||
|
制造商开始从其他方面提高处理器的性能, 但这中解决方案也有其自身的局限性。因为成本原因我们不能无限制的为计算机添加内核,也无法无限制的添加缓存来提高性能,因为缓存越大,取值的性能越低。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
```shell
|
|||
|
* 1.向处理器添加越来越多的内核,如四核和八核CPU。
|
|||
|
* 2.发明了超线程技术。
|
|||
|
* 3.为处理器添加了更多缓存以提高性能。
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Tips : 一旦我们没有办法在硬件上一直取得突破,我们只能提高软件的性能或者说我们需要高性能的软件。
|
|||
|
|
|||
|
如上所述,硬件制造商正在为处理器添加越来越多的内核以提高性能。所有数据中心都在这些处理器上运行,更重要的是,今天的应用程序使用多个微服务来维护数据库连接,消息队列和维护缓存。因此,开发的软件和编程语言应该可以轻松地支持并发性,并且应该能够随着CPU核心数量的增加而可扩展。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**发展历史**
|
|||
|
描述: 大多数现代编程语言(如Java,Python等)都来自90年代的单线程环境。虽然一些编程语言的框架在不断地提高多核资源使用效率,例如 Java 的 Netty 等,但仍然需要开发人员花费大量的时间和精力搞懂这些框架的运行原理后才能熟练掌握。
|
|||
|
|
|||
|
- Go 于 2007年9月由于`罗伯特·格瑞史莫、罗勃·派克及肯·汤普逊于开始设计,[3]稍后伊恩·兰斯·泰勒(Ian Lance Taylor)、拉斯·考克斯(Russ Cox)`加入项目。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- Go 于 2009年11月正式宣布推出,版本1.0在2012年3月发布,之后Go广泛应用于Google的产品以及许多其他组织和开源项目。
|
|||
|
- Go 于 2009年11月10日由Google发布推出,成为开放源代码项目,支持Linux、macOS、Windows等操作系统。2005 年 AMD 速龙发布第一款民用级多核处理器,所以当时多核处理器已经上市。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
Tips : 在2016年,Go 被软件评价公司TIOBE选为`"TIOBE 2016年最佳语言"`。
|
|||
|
|
|||
|
# What,什么是Go语言?
|
|||
|
|
|||
|
描述:`Go(又称Golang[4]-Google-go-language)`是Google开发的一种`静态强类型`、`编译型`、`并发型`,并具有`垃圾回收功能、优良的并行设计`的编程语言, 其被誉为21世纪的C语言, 因为其Go的语法接近C语言,但对于变量的声明有所不同。
|
|||
|
|
|||
|
Go的并行计算模型是`以东尼·霍尔`的通信顺序进程(CSP)为基础,采取类似模型的其他语言包括`Occam`和`Limbo`,Go也具有这个模型的特征,比如通道传输,通过`goroutine`和通道等并行构造可以建造线程池和管道等。
|
|||
|
|
|||
|
- (1) 与 `C++` 相比 Go 并不包括如`枚举、异常处理、继承、泛型、断言、虚函数`等功能,但增加了`切片(Slice) 型、并发、管道、垃圾回收功能、接口等`特性的语言级支持以及支持垃圾回收功能。
|
|||
|
- (2) 不同于 Java,Go原生提供了关联数组(也称为`哈希表(Hashes)`或`字典(Dictionaries)`)。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**Goroutine 并行设计**
|
|||
|
描述:
|
|||
|
|
|||
|
透过Goroutine能够让程序以异步的方式运行,而不需要担心一个函数导致程序中断,因此Go也非常地适合网络服务。
|
|||
|
|
|||
|
假设有个程序,里面有两个函数:
|
|||
|
|
|||
|
```go
|
|||
|
func main() {
|
|||
|
// 假設 loop 是一個會重複執行十次的迴圈函式。
|
|||
|
// 迴圈執行完畢才會往下執行。
|
|||
|
loop()
|
|||
|
// 執行另一個迴圈。
|
|||
|
loop()
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
如此就不需要等待该函数运行完后才能运行下一个函数。
|
|||
|
|
|||
|
```go
|
|||
|
func main() {
|
|||
|
// 透過 `go`,我們可以把這個函式同步執行,
|
|||
|
// 如此一來這個函式就不會阻塞主程式的執行。
|
|||
|
go loop()
|
|||
|
// 執行另一個迴圈。
|
|||
|
loop()
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**参考来源:**
|
|||
|
Wiki 百科 : https://wiki.weiyigeek.top/w/index.php?search=go&title=Special:搜索&go=前往
|
|||
|
官方网站 :
|
|||
|
|
|||
|
- https://golang.org/
|
|||
|
- https://golang.google.cn/
|
|||
|
|
|||
|
# Why,为啥要用Go语言?
|
|||
|
|
|||
|
**Go 语言有何特点:**
|
|||
|
|
|||
|
- 0.Go语言语法简单易学、代码风格统一`(自动格式化)`、支持垃圾回收功能、执行性能好、是企业级编程语言。
|
|||
|
|
|||
|
> Go 语言简单易学,学习曲线平缓,不需要像 C/C++ 语言动辄需要两到三年的学习期。
|
|||
|
> Go 语言的风格类似于C语言。其语法在C语言的基础上进行了大幅的简化,去掉了不需要的表达式括号,循环也只有 for 一种表示方法,就可以实现数值、键值等各种遍历。
|
|||
|
> Go 语言提供了一套格式化工具`go fmt`, 在开发环境或者编辑器在保存时,都会使用格式化工具进行修改代码的格式化,这样就保证了不同开发者提交的代码都是统一的格式。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 1.Go语言让你用写Python代码的开发效率编写C语言代码 (`编程范型: 编译型,可平行化,结构化,指令式`)。
|
|||
|
- 2.Go语言从底层原生支持并发,无须第三方库、开发者的编程技巧和开发经验。
|
|||
|
|
|||
|
> Go语言的并发是基于 goroutine(`类似于线程,但并非线程`) 的。可以将 goroutine 理解为一种虚拟线程。Go 语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每个 CPU 中,最大限度地使用CPU性能。开启一个goroutine的消耗非常小(`大约2KB的内存`),你可以轻松创建数百万个goroutine。
|
|||
|
> goroutine的特点:
|
|||
|
|
|||
|
\* 具有可增长的分段堆栈。这意味着它们只在需要时才会使用更多内存。 * 启动时间比线程快。 * 原生支持利用channel安全地进行通信。 * 共享数据结构时无需使用互斥锁。
|
|||
|
|
|||
|
- 3.Go语言性能强悍,同`C,C++`一样Go语言也是编译型的语言,它直接将人类可读的代码编译成了处理器可以直接运行的二进制文件,执行效率更高,性能更好。
|
|||
|
|
|||
|
解释型语言:Shell 语言、Python 语言、PHP 语言 编译型语言:C 语言、C++ 语言、Go 语言
|
|||
|
|
|||
|

|
|||
|
|
|||
|
由下图可以看出,Go 语言在性能上更接近于 Java 语言,虽然在某些测试用例上不如经过多年优化的 Java 语言,但毕竟 Java 语言已经经历了多年的积累和优化。Go 语言在未来的版本中会通过不断的版本优化提高单核运行性能。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
数据来源:https://benchmarksgame-team.pages.debian.net/benchmarksgame/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**Go 语言的缺陷**
|
|||
|
|
|||
|
Tips : Go 2.0 版本将支持泛型,对于断言的存在,则持负面态度,同时也为自己不提供类型继承来辩护。
|
|||
|
|
|||
|
# How,Go语言发展前景?
|
|||
|
|
|||
|
目前Go语言已经⼴泛应用于人工智能、云计算开发、容器虚拟化、⼤数据开发、数据分析及科学计算、运维开发、爬虫开发、游戏开发等领域。
|
|||
|
|
|||
|
Go语言简单易学,天生支持并发,完美契合当下高并发的互联网生态,并且在多核并发上拥有原生的设计优势, 很多公司,特别是中国的互联网公司,即将或者已经完成了使用 Go 语言改造旧系统的过程。经过 Go 语言重构的系统能使用更少的硬件资源获得更高的并发和I/O吞吐表现。充分挖掘硬件设备的潜力也满足当前精细化运营的市场大环境。
|
|||
|
|
|||
|
所以当下程序开发者应该抓住趋势,要学会做一个领跑者而不是跟随者。
|
|||
|
国内Go语言的需求潜力巨大,目前无论是国内大厂还是新兴互联网公司基本上都会有Go语言的岗位需求。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**Go 在互联网企业应用以及使用它的公司:**
|
|||
|
|
|||
|
- Go在百度内部应用(百度流量入口BFE、自动驾驶、百度只能小程序、百度APP)
|
|||
|
- Go在腾讯内部应用(蓝鲸运维平台、微服务框架TarsGo、云平台)
|
|||
|
- Go在知乎内部应用(知乎全站重构)
|
|||
|
|
|||
|

|
|||
|
|
|||
|
现在就开始你的Go语言学习之旅吧!人生苦短,let’s Go, 下面我们将进行Go开发环境安装实践。
|
|||
|
|
|||
|
# 0x01 Go语言开发环境搭建
|
|||
|
|
|||
|
描述: 本章节主要讲解安装Go语言及搭建Go语言开发环境。
|
|||
|
|
|||
|
Tips : Go语言1.11版本之后,开启go mod模式之后就不再强制需要配置GOPATH了。
|
|||
|
Tips : Go语言1.14版本之后,推荐使用go modules管理依赖,也不再需要把代码写在GOPATH目录下了,之前旧版本的教程戳这个链接。
|
|||
|
|
|||
|
**下载地址:**
|
|||
|
Go官网下载 : https://golang.org/dl/
|
|||
|
Go官方镜像站(推荐):https://golang.google.cn/dl/ & https://studygolang.com/dl
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# 版本平台
|
|||
|
|
|||
|
描述: Windows平台和Mac平台推荐下载可执行文件版,Linux平台下载压缩文件版。
|
|||
|
|
|||
|
当前 2021年7月28日 22:43:15 最新版本为1.16.16版。
|
|||
|
|
|||
|
- Source: 源代码编译安装-https://dl.google.com/go/go1.16.6.src.tar.gz
|
|||
|
- Binary: 二进制解压安装-https://dl.google.com/go/go1.16.6.linux-amd64.tar.gz
|
|||
|
|
|||
|
Tips :由于时间的推移的1.16.6版本号可能并不是最新的,但总体来说安装教程是类似的,Go语言更新迭代比较快,推荐使用较新版本,体验最新特性。
|
|||
|
|
|||
|
**Windows**
|
|||
|
描述: 此安装实例以 64位 Win10 系统安装 `Go 1.14.1` 可执行文件版本为例, 双击下载好的文件,然后按照下图的步骤安装即可。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
**Linux**
|
|||
|
如果不是要在Linux平台敲go代码就不需要在Linux平台安装Go,我们开发机上写好的go代码只需要跨平台编译(详见文章末尾的跨平台编译)好之后就可以拷贝到Linux服务器上运行了,这也是go程序跨平台易部署的优势。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
```shell
|
|||
|
#1.下载二进制源码包并将将下载的源码包解压至 /usr/local目录
|
|||
|
wget https://dl.google.com/go/go1.16.6.linux-amd64.tar.gz
|
|||
|
tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz
|
|||
|
|
|||
|
#2.将 /usr/local/go/bin 目录添加至PATH环境变量
|
|||
|
#在/root/.profile进行添加
|
|||
|
export GOROOT=/usr/local/go # 安装目录
|
|||
|
#GOROOT 第三方包的安装包路径
|
|||
|
export GOPATH=/home/go/ # 项目路径一般指向src
|
|||
|
#需要BIN目录和GOPATH
|
|||
|
export PATH=$PATH:$GOROOT/bin
|
|||
|
|
|||
|
#3.验证是否安装成功, 可以打开终端窗口输入go version命令,查看安装的Go版本。
|
|||
|
go env
|
|||
|
go version go version go1.16.6 linux/amd64
|
|||
|
|
|||
|
#4.go语言程序编译运行
|
|||
|
package main
|
|||
|
import "fmt"
|
|||
|
func main() {
|
|||
|
fmt.Println("Hello, World!")
|
|||
|
}
|
|||
|
|
|||
|
#5.编译运行hello.go
|
|||
|
go build hello.go
|
|||
|
go run hello.go && ./hello
|
|||
|
```
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
# 开发环境
|
|||
|
|
|||
|
描述: 由于本人习惯于使用Ubuntu作为开发环境,此处Go语言的学习环境以`Ubuntu 20.04 Desktop`版本为例进行。
|
|||
|
|
|||
|
# (1) Ubuntu桌面版
|
|||
|
|
|||
|
- Ubuntu 20.04 LTS Desktop 操作系统 : https://ubuntu.com/download/desktop
|
|||
|
- Ubuntu 20.04 LTS Desktop 基本配置 : https://mp.weixin.qq.com/s/6Ip[AV5](https://www.bilibili.com/video/AV5)-Hdi-mpbH9XlTCOw
|
|||
|
|
|||
|
```shell
|
|||
|
# (1) xrdp 安装与配置 : https://mp.weixin.qq.com/s/JA04lJrQETDXP0N_mrthJg
|
|||
|
# xfce4 桌面
|
|||
|
# echo xfce4-session > ~/.xsession
|
|||
|
|
|||
|
# (2) ZSH 命令行终端优化 : https://mp.weixin.qq.com/s/8i0K2D-hp51U6UFOd25c2Q
|
|||
|
|
|||
|
# (3) 中文输入法安装 :
|
|||
|
- https://pinyin.sogou.com/linux/help.php
|
|||
|
- https://srf.baidu.com/site/guanwang_linux/index.html
|
|||
|
```
|
|||
|
|
|||
|
- Ubuntu 20.04 LTS Desktop 安装配置 Go 语言:
|
|||
|
|
|||
|
```shell
|
|||
|
# 环境变量
|
|||
|
vim /etc/profile.d/golang-env.sh
|
|||
|
export GOROOT=/home/weiyigeek/app/program/go
|
|||
|
export GOPATH=/home/weiyigeek/app/program/project/go
|
|||
|
export PATH=${PATH}:${GOROOT}/bin
|
|||
|
|
|||
|
# 创建 bin,pkg,src
|
|||
|
mkdir -vp ${GOPATH}/{bin,pkg,src}
|
|||
|
mkdir: 已创建目录 'go'
|
|||
|
mkdir: 已创建目录 'go/bin' # 用于存放编译后生成的可执行文件
|
|||
|
mkdir: 已创建目录 'go/pkg' # 用于存放编译生成的归档文件
|
|||
|
mkdir: 已创建目录 'go/src' # 用于存储源码文件代理包以及自开发包
|
|||
|
|
|||
|
# 重开Shell验证版本
|
|||
|
source /etc/profile
|
|||
|
go version
|
|||
|
# go version go1.16.6 linux/amd64
|
|||
|
```
|
|||
|
|
|||
|
**环境变量:**
|
|||
|
描述: 利用 `go env` 命令查看相关go语言相关的环境变量
|
|||
|
|
|||
|
```shell
|
|||
|
GO111MODULE="on"
|
|||
|
GOARCH="amd64"
|
|||
|
GOBIN=""
|
|||
|
GOCACHE="/home/weiyigeek/.cache/go-build"
|
|||
|
GOENV="/home/weiyigeek/.config/go/env"
|
|||
|
GOEXE=""
|
|||
|
GOFLAGS=""
|
|||
|
GOHOSTARCH="amd64"
|
|||
|
GOHOSTOS="linux"
|
|||
|
GOINSECURE=""
|
|||
|
GOMODCACHE="/home/weiyigeek/app/program/project/go/pkg/mod"
|
|||
|
GONOPROXY=""
|
|||
|
GONOSUMDB=""
|
|||
|
GOOS="linux"
|
|||
|
GOPATH="/home/weiyigeek/app/program/project/go"
|
|||
|
GOPRIVATE=""
|
|||
|
GOPROXY="https://goproxy.cn,direct"
|
|||
|
GOROOT="/home/weiyigeek/app/program/go"
|
|||
|
GOSUMDB="sum.golang.org"
|
|||
|
GOTMPDIR=""
|
|||
|
GOTOOLDIR="/home/weiyigeek/app/program/go/pkg/tool/linux_amd64"
|
|||
|
GOVCS=""
|
|||
|
GOVERSION="go1.16.6"
|
|||
|
GCCGO="gccgo"
|
|||
|
AR="ar"
|
|||
|
CC="gcc"
|
|||
|
CXX="g++"
|
|||
|
CGO_ENABLED="1"
|
|||
|
GOMOD="/dev/null"
|
|||
|
CGO_CFLAGS="-g -O2"
|
|||
|
CGO_CPPFLAGS=""
|
|||
|
CGO_CXXFLAGS="-g -O2"
|
|||
|
CGO_FFLAGS="-g -O2"
|
|||
|
CGO_LDFLAGS="-g -O2"
|
|||
|
PKG_CONFIG="pkg-config"
|
|||
|
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3886050940=/tmp/go-build -gno-record-gcc-switches"
|
|||
|
```
|
|||
|
|
|||
|
**常用变量解析:**
|
|||
|
|
|||
|
- GOROOT : 指定安装Go语言开发包的解压路径。
|
|||
|
- GOPATH : 指定外部Go语言代码开发工作区目录, 从`Go 1.8`版本开始Go开发包在安装完成后会为GOPATH设置一个默认目录,并且在`Go 1.14`及之后的版本中启用了`Go Module`模式之后,不一定非要将代码写到`GOPATH`目录下,所以也就不需要我们再自己配置GOPATH了使用默认的即可。
|
|||
|
|
|||
|
```shell
|
|||
|
# - 在 Go 1.8 版本之前,GOPATH环境变量默认是空的。从 Go 1.8 版本开始,Go 开发包在安装完成后会为 GOPATH设置一个默认目录,参见下述。
|
|||
|
# GOPATH在不同操作系统平台上的默认值
|
|||
|
平台 GOPATH默认值 举例
|
|||
|
Windows %USERPROFILE%/go C:\Users\用户名\go
|
|||
|
Unix $HOME/go /home/用户名/go
|
|||
|
|
|||
|
# - 同时,我们将 GOROOT下的bin目录及GOPATH下的bin目录都添加到环境变量中。
|
|||
|
|
|||
|
# - 配置环境变量之后需要重启你电脑上已经打开的终端。(例如cmd、VS Code里面的终端和其他编辑器的终端)。
|
|||
|
```
|
|||
|
|
|||
|
- GOPROXY : 指定代理Go语言从公共代理仓库中快速拉取您所需的依赖代码(建议 Go > 1.13)。
|
|||
|
|
|||
|
```shell
|
|||
|
# - 1. goproxy.io 是全球最早的 Go modules 镜像代理服务之一, 采用 CDN 加速服务为开发者提供依赖下载, 该服务由一批热爱开源, 热爱 Go 语言的年轻人开发维护。
|
|||
|
# - 2. goproxy.cn 中国最可靠的 Go 模块代理, 由七牛云 CDN 在全球范围内加速我们的服务。
|
|||
|
# - 3. goproxy.baidu.com 百度Go Module代理仓库服务, 你可以利用该代理来避免DNS污染导致的模块拉取缓慢或失败的问题加速你的构建。
|
|||
|
|
|||
|
# Go 1.13 及以上(推荐)
|
|||
|
$ go env -w GO111MODULE=on
|
|||
|
$ go env -w GOPROXY=https://goproxy.cn,direct
|
|||
|
$ go env -w GOPROXY=https://goproxy.io,direct
|
|||
|
$ go env -w GOPROXY=https://goproxy.baidu.com/,direct
|
|||
|
|
|||
|
# Bash (Linux or macOS)
|
|||
|
# 配置 GOPROXY 环境变量
|
|||
|
export GO111MODULE=on
|
|||
|
export GOPROXY=https://goproxy.io,direct
|
|||
|
# 还可以设置不走 proxy 的私有仓库或组,多个用逗号相隔(可选)
|
|||
|
export GOPRIVATE=git.mycompany.com,github.com/my/private
|
|||
|
|
|||
|
# PowerShell (Windows)
|
|||
|
# 配置 GOPROXY 环境变量
|
|||
|
$env:GO111MODULE = "on"
|
|||
|
$env:GOPROXY = "https://goproxy.io,direct"
|
|||
|
# 还可以设置不走 proxy 的私有仓库或组,多个用逗号相隔(可选)
|
|||
|
$env:GOPRIVATE = "git.mycompany.com,github.com/my/private"
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# (2) 开发编辑器
|
|||
|
|
|||
|
描述: Go采用的是UTF-8编码的文本文件存放源代码,理论上使用任何一款文本编辑器都可以做Go语言开发,这里推荐使用`VS Code`和`Goland`。
|
|||
|
|
|||
|
- VS Code 是微软开源的编辑器
|
|||
|
- Goland 是jetbrains出品的付费IDE。
|
|||
|
|
|||
|
**2.1 Visual Studio Code**
|
|||
|
描述: VS Code全称Visual Studio Code,是微软公司开源的一款免费现代化轻量级代码编辑器,支持几乎所有主流的开发语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性,支持插件扩展,支持 Win、Mac 以及 Linux平台。
|
|||
|
|
|||
|
Tips : 虽然不如某些IDE功能强大,但是它添加Go扩展插件后已经足够胜任我们日常的Go开发, 并支持三大主流平台都支持,请根据自己的电脑平台选择对应的安装包。
|
|||
|
|
|||
|
VS Code 官方下载地址:https://code.visualstudio.com/Download
|
|||
|
|
|||
|
- Step 1.在Ubuntu中安装deb格式的 `VS code` 开发软件。
|
|||
|
|
|||
|
```shell
|
|||
|
$ wget https://az764295.vo.msecnd.net/stable/c3f126316369cd610563c75b1b1725e0679adfb3/code_1.58.2-1626302803_amd64.deb
|
|||
|
$ dpkg -i ode_1.58.2-1626302803_amd64.deb
|
|||
|
$ code
|
|||
|
1.58.2
|
|||
|
c3f126316369cd610563c75b1b1725e0679adfb3
|
|||
|
x64
|
|||
|
```
|
|||
|
|
|||
|
- Step 2.VS Code 基础 Go 开发环境配置
|
|||
|
|
|||
|
```shell
|
|||
|
# (1) 安装中文简体插件:
|
|||
|
> 点击左侧菜单栏最后一项管理扩展,在搜索框中输入 chinese ,选中结果列表第一项,点击install安装。
|
|||
|
> 安装完毕后右下角会提示重启 `VS Code`,重启之后你的`VS Code`就显示中文啦!
|
|||
|
|
|||
|
# (2) 安装Go扩展:
|
|||
|
> 现在我们要为我们的`VS Code`编辑器安装Go扩展插件,让它支持Go语言开发,在搜索框中输入 chinese 。
|
|||
|
|
|||
|
# (3) 安装Go语言开发工具包:
|
|||
|
> 在Go语言开发的时候为我们提供诸如代码提示、代码自动补全等功能。
|
|||
|
> 在此之前请先设置GOPROXY,打开终端执行以下命令: go env -w GOPROXY=https://goproxy.cn,direct
|
|||
|
> Windows平台按下`Ctrl+Shift+P`,Mac平台按`Command+Shift+P`,这个时候VS Code界面会弹出一个输入框,如下图:
|
|||
|
> 我们在这个输入框中输入 `go:install`,下面会自动搜索相关命令,我们选择 `Go:Install/Update Tools`这个命令,按下图选中并会回车执行该命令(或者使用鼠标点击该命令)
|
|||
|
> 在弹出的窗口选中所有,并点击“确定”按钮,进行安装。
|
|||
|
# Tools environment: GOPATH=/home/weiyigeek/app/program/project/go
|
|||
|
# Installing 10 tools at /home/weiyigeek/app/program/project/go/bin in module mode.
|
|||
|
# gopkgs
|
|||
|
# go-outline
|
|||
|
# gotests
|
|||
|
# gomodifytags
|
|||
|
# impl
|
|||
|
# goplay
|
|||
|
# dlv
|
|||
|
# dlv-dap
|
|||
|
# staticcheck
|
|||
|
# gopls
|
|||
|
> 最终会在终端中显示 successful 则为安装成功。
|
|||
|
```
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- Step 3.编辑器主题变更,依次点击设置->颜色主题,然后在弹出的窗口选择你喜欢的主题, 本人比较喜欢使用Dark 暗黑的主题。
|
|||
|
- Step 4.配置VSCode开启自动保存,依次点击 文件->首选项->设置,打开设置页面就能看到自动保存相关配置如下图,可以根据自己的喜好选择自动保存的方式:
|
|||
|
- Step 5.配置代码片段快捷键,还是按Ctrl/Command+Shift+P,按下图输入>snippets,选择命令并执行, 然后在弹出的窗口点击选择go选项,然后弹出如下代码页面:
|
|||
|
|
|||
|
```shell
|
|||
|
# 用法:
|
|||
|
"代码块主要名称":{
|
|||
|
"prefix": "快捷键简写",
|
|||
|
"body": "这里是按快捷键插入的代码片段",
|
|||
|
"description": "这里放提示信息的描述"
|
|||
|
}
|
|||
|
|
|||
|
# 示例: 其中$0表示最终光标提留的位置。 举个例子,我这里创建了两个快捷方式,一个是输入pln就会在编辑器中插入fmt.Println()代码;输入plf,就会插入fmt.Printf("")代码。
|
|||
|
{
|
|||
|
"initcode":{
|
|||
|
"prefix": "init",
|
|||
|
"body": [
|
|||
|
"package main",
|
|||
|
"import \"fmt\"",
|
|||
|
"func main(){",
|
|||
|
"fmt.Println($0)",
|
|||
|
"}",
|
|||
|
],
|
|||
|
"description": "快速插入一个简单的Go Main 示例代码块"
|
|||
|
},
|
|||
|
|
|||
|
"println":{
|
|||
|
"prefix": "pln",
|
|||
|
"body":"fmt.Println($0)",
|
|||
|
"description": "Println,Line feed printing"
|
|||
|
},
|
|||
|
|
|||
|
"printf":{
|
|||
|
"prefix": "ptf",
|
|||
|
"body": "fmt.Printf(\"$0\")",
|
|||
|
"description": "printf,Normal printout"
|
|||
|
},
|
|||
|
|
|||
|
"sprintf":{
|
|||
|
"prefix": "sptf",
|
|||
|
"body": "fmt.Sprintf(\"$0\")",
|
|||
|
"description": "将拼接的字符串返回给变接收量"
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|

|
|||
|
|
|||
|
- Step 6.把上面的代码,按下图方式粘贴到配置文件中,保存并关闭配置文件即可。然后我们打开一个go文件,测试一下效果:
|
|||
|
|
|||
|
GIF
|
|||
|
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
# Let,Go
|
|||
|
|
|||
|
描述: 此处是学习一门新语言的常规操作输出 Hello World , 现在我们来创建第一个Go项目 hello.go
|
|||
|
|
|||
|
**初始化项目: go mod init**
|
|||
|
描述: 使用go module模式新建项目时,我们需要通过 `go mod init 项目名`命令对项目进行初始化,该命令会在项目根目录下生成go.mod文件。
|
|||
|
|
|||
|
例如,我们使用hello作为我们第一个Go项目的名称,执行如下命令` go mod init hello`。
|
|||
|
|
|||
|
\```bash
|
|||
|
|
|||
|
\# go.mod
|
|||
|
|
|||
|
module hello
|
|||
|
|
|||
|
go 1.16
|
|||
|
|
|||
|
\```
|
|||
|
|
|||
|
# Hello World
|
|||
|
|
|||
|
描述: 接下来在该目录中创建一个helloWorld.go文件
|
|||
|
|
|||
|
```go
|
|||
|
// 声明 main 包表明当前是一个可执行程序
|
|||
|
package main
|
|||
|
|
|||
|
// 导入内置 fmt 包供内部函数使用
|
|||
|
import "fmt"
|
|||
|
|
|||
|
// Main 函数程序入口主函数
|
|||
|
func main() {
|
|||
|
// 终端输出打印语句
|
|||
|
fmt.Println("Hello World, Let's Go.")
|
|||
|
/**
|
|||
|
此处为多行注释
|
|||
|
**/
|
|||
|
fmt.Println("人生苦短现在,开启你的Go语言学习之旅吧。")
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Tips : 我们可以在`VScode`配置go项目的Debug调试模式便可以直接使用`快捷键F5`进行快速测试编写的程序。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
Tips : 我们知道作为编译型的语言Go与C语言一样需要编译然后再运行。
|
|||
|
|
|||
|
Tips : Go 语言函数外的语句必须以关键字开头。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**编译: go Build**
|
|||
|
描述: `go build` 命令表示将源代码编译成可执行文件。
|
|||
|
|
|||
|
在hello目录下执行`go build`(指定.go文件)或者在其他目录执行以下命令`go build helloworld`(项目需要在GOROOT路径的src目录之中),因为go编译器会去 GOPATH 的src目录下查找你要编译的hello项目
|
|||
|
|
|||
|
|
|||
|
|
|||
|
```shell
|
|||
|
# - 目录下执行
|
|||
|
➜ Day01 pwd
|
|||
|
/home/weiyigeek/develop/github-project/Go/Day01
|
|||
|
➜ Day01 go build
|
|||
|
➜ Day01 ./Day01
|
|||
|
Hello World, Let Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
|
|||
|
# - 指定main包所在的.go文件
|
|||
|
➜ Day01 go build HelloWorld.go
|
|||
|
➜ Day01 ./HelloWorld
|
|||
|
Hello World, Lets Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
|
|||
|
# - 使用-o参数来指定编译后得到的可执行文件的名字
|
|||
|
➜ Day01 go build -o ahelloworld.
|
|||
|
➜ Day01 ./ahelloworld
|
|||
|
Hello World, Let's Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
```
|
|||
|
|
|||
|
Tips : 如上述编译得到的可执行文件会保存在执行编译命令的当前目录下会有 HelloWorld 可执行文件,如果是windows平台会在当前目录下找到HelloWorld.exe可执行文件。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
**编译&运行: go Run**
|
|||
|
描述: 我们也可以直接执行程序,该命令本质上也是先编译再执行。
|
|||
|
|
|||
|
```shell
|
|||
|
➜ Day01 go run HelloWorld.go
|
|||
|
Hello World, Let's Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
```
|
|||
|
|
|||
|
**编译&安装软件包&依赖项: go Install**
|
|||
|
描述: go install 表示安装的意思,它先编译源代码得到可执行文件,然后将可执行文件移动到GOPATH的bin目录下。因为我们的环境变量中配置了GOPATH下的bin目录,所以我们就可以在任意地方直接执行可执行文件了。
|
|||
|
|
|||
|
```shell
|
|||
|
➜ Day01 go install # 生成 Day01 可执行文件
|
|||
|
➜ Day01 go install HelloWorld.go # 生成 HelloWorld 可执行文件
|
|||
|
➜ Day01 ls ${GOROOT}
|
|||
|
➜ Day01 ls ${GOPATH}/bin/
|
|||
|
# Day01 dlv dlv-dap gomodifytags go-outline gopkgs goplay gopls gotests HelloWorld impl staticcheck
|
|||
|
➜ Day01 /home/weiyigeek/app/program/project/go/bin/Day01
|
|||
|
Hello World, Let's Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
```
|
|||
|
|
|||
|
**跨平台编译: CGO_ENABLED / GOOS / GOARCH**
|
|||
|
描述: 默认我们go build的可执行文件都是当前操作系统可执行的文件,如果我想在windows下编译一个linux下可执行文件,那需要怎么做呢?
|
|||
|
|
|||
|
只需要指定目标操作系统的平台和处理器架构即可,例如Windows平台cmd下按如下方式指定环境变量编译出的可以执行文件则可以在Linux 操作系统 amd64 处理器中执行,然后再执行go build命令,得到的就是能够在Linux平台运行的可执行文件了。
|
|||
|
|
|||
|
```shell
|
|||
|
SET CGO_ENABLED=0 # 禁用CGO
|
|||
|
SET GOOS=linux # 目标平台是linux
|
|||
|
SET GOARCH=amd64 # 目标处理器架构是amd64
|
|||
|
```
|
|||
|
|
|||
|
注意:如果你使用的是PowerShell终端,那么设置环境变量的语法为 $ENV:CGO_ENABLED=0。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
不同平台快速交叉编译:
|
|||
|
|
|||
|
```shell
|
|||
|
# 目标平台是linux
|
|||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
|
|||
|
# 目标平台Windows
|
|||
|
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
|
|||
|
# 目标平台Mac
|
|||
|
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
|
|||
|
```
|
|||
|
|
|||
|
简单实践: 在Liunx平台上编译出在`Windows`上运行的`helloWorld.exe`可执行文件。
|
|||
|
|
|||
|
```shell
|
|||
|
# Linux
|
|||
|
➜ Day01 CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o Win-HelloWorld.exe
|
|||
|
➜ Day01 ls
|
|||
|
HelloWorld.go Win-HelloWorld.exe
|
|||
|
|
|||
|
# Windows: 拷贝后执行
|
|||
|
PS D:\Temp> .\Win-HelloWorld.exe
|
|||
|
Hello World, Let's Go.
|
|||
|
人生苦短现在,开启你的Go语言学习之旅吧。
|
|||
|
```
|
|||
|
|
|||
|
Tips : 对比不同平台交叉编译后的可执行文件大小。
|
|||
|
|
|||
|
```shell
|
|||
|
➜ Day01 ls -la --ignore HelloWorld.go
|
|||
|
-rwxrwxr-x 1 weiyigeek weiyigeek 1937799 7月 30 03:23 helloworld # ~ 1.9 MB
|
|||
|
-rwxrwxr-x 1 weiyigeek weiyigeek 2027936 7月 30 03:24 Mac-HelloWorld # ~ 2.0 MB
|
|||
|
-rwxrwxr-x 1 weiyigeek weiyigeek 2098688 7月 30 02:58 Win-HelloWorld.exe # ~ 2.1 MB
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# Http Web Server
|
|||
|
|
|||
|
描述: 透过Go仅需几行代码就完成HTTP网页服务器的实现。
|
|||
|
|
|||
|
```go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"io"
|
|||
|
"net/http"
|
|||
|
)
|
|||
|
|
|||
|
func hello(w http.ResponseWriter, r *http.Request) {
|
|||
|
io.WriteString(w, "Hello world!")
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
http.HandleFunc("/", hello)
|
|||
|
http.ListenAndServe(":8000", nil)
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
# Echo 类似命令程序
|
|||
|
|
|||
|
描述: 用Go去实现一个像Unix中的Echo命令程序。
|
|||
|
|
|||
|
```go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"os"
|
|||
|
"flag"
|
|||
|
)
|
|||
|
|
|||
|
var omitNewline = flag.Bool("n", false, "don't print final newline")
|
|||
|
|
|||
|
const (
|
|||
|
Space = " "
|
|||
|
Newline = "\n"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
flag.Parse() // Scans the arg list and sets up flags
|
|||
|
var s string = ""
|
|||
|
for i = 0; i < flag.NArg(); i++ {
|
|||
|
if i > 0 {
|
|||
|
s += Space
|
|||
|
}
|
|||
|
s += flag.Arg(i)
|
|||
|
}
|
|||
|
if !*omitNewline {
|
|||
|
s += Newline
|
|||
|
}
|
|||
|
os.Stdout.WriteString(s)
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# 0x02 Go 项目结构
|
|||
|
|
|||
|
在进行Go语言开发的时候,我们的代码总是会保存在`$GOPATH/src`目录下。在工程经过`go build、go install`或`go get`等指令后,会将下载的第三方包源代码文件放在 `$GOPATH/src` 目录下,产生的二进制可执行文件放在 `$GOPATH/bin`目录下,生成的中间缓存文件会被保存在 `$GOPATH/pkg` 下。
|
|||
|
|
|||
|
Tips : 如果我们使用版本管理工具`(Version Control System,VCS。常用如Git/Svn)`来管理我们的项目代码时,我们只需要添加`$GOPATH/src`目录的源代码即可, bin 和 pkg 目录的内容无需版本控制。
|
|||
|
|
|||
|
|
|||
|
|
|||
|
通常来讲`GOPATH`目标下文件目录组织架构的设置常常有以下三种:
|
|||
|
|
|||
|
# (1)适合个人开发者
|
|||
|
|
|||
|
描述: 我们知道源代码都是存放在GOPATH的src目录下,那我们可以按照下图来组织我们的代码。
|
|||
|
|
|||
|
适合个人开发者
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# (2)适合企业开发场景
|
|||
|
|
|||
|
描述: 此种目录结构设置更适合企业开发环境,以代码仓库为前缀并以公司内部组织架构为基准,其次是项目名称,最后是各个模块开发的名称。
|
|||
|
|
|||
|
适合企业开发场景
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# (3)目前流行的项目结构
|
|||
|
|
|||
|
描述: Go语言中也是通过包来组织代码文件,我们可以引用别人的包也可以发布自己的包,但是为了防止不同包的项目名冲突,我们通常使用顶级域名来作为包名的前缀,这样就不担心项目名冲突的问题了。
|
|||
|
|
|||
|
因为不是每个个人开发者都拥有自己的顶级域名,所以目前流行的方式是使用个人的github用户名来区分不同的包。
|
|||
|
|
|||
|
目前流行的项目结构
|
|||
|
|
|||
|
- 举例说明: 张三和李四都有一个名叫studygo的项目,那么这两个包的路径就会是:
|
|||
|
|
|||
|
```go
|
|||
|
import "github.com/zhangsan/studygo"
|
|||
|
import "github.com/lisi/studygo"
|
|||
|
```
|
|||
|
|
|||
|
- 举例说明: 同样如果我们需要从`githuab`上下载别人包的时候如:`go get github.com/jmoiron/sqlx`, 那么这个包会下载到我们本地GOPATH目录下的`src/github.com/jmoiron/sqlx`。
|
|||
|
|
|||
|
总结说明: 后续我们的开发学习示例基本按照第三种项目结构进行。
|