golang-study/notes/1.入门篇.md
2021-09-11 18:30:18 +08:00

766 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

**目录一览:**
- 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)目前流行的项目结构
![img](assets/4aa545dccf7de8d4a93c2b2b8e3265ac0a26d216.png@progressive.webp)
# 0x00 前言简述
**为什么你应该学习Go语言**
> 世界上已经有太多太多的编程语言了为什么又出来一个Go语言
> 因为其编程语言的良好特性和Google公司强势推广以及以Go语言相关开源项目火爆, 比如 `etcd、kubernetes、Prometheus` 等项目, 其次是硬件性能提高则我们需要高性能的软件
- 1.参考 Golang 编程语言排行榜 : https://www.tiobe.com/tiobe-index
![WeiyiGeek.2010-2021年Go编程趋势](assets/f5e12e4882753fee5ba818396bd935485663654d.png@942w_741h_progressive.webp)
- 2.硬件限制(摩尔定律)已然失效
> 摩尔定律当价格不变时集成电路上可容纳的元器件的数目约每隔18-24个月便会增加一倍性能也将提升一倍。 换言之每一美元所能买到的电脑性能将每隔18-24个月翻一倍以上。
![WeiyiGeek.1975-2015年处理器集体管数量](assets/bb07174f845a5c5495945a63f03d5870a832d1d7.png@900w_624h_progressive.webp)
从上面的图表可以看出近十年单线程性能和处理器频率保持稳定。我们不能像之前一样把添加更多晶体管当成是解决方案因为在较小规模上一些量子特性开始出现如隧道效应并且因为在同样小的空间里放置更多晶体管的代价非常昂贵每1美元可以添加的晶体管数量开始下降。
制造商开始从其他方面提高处理器的性能, 但这中解决方案也有其自身的局限性。因为成本原因我们不能无限制的为计算机添加内核,也无法无限制的添加缓存来提高性能,因为缓存越大,取值的性能越低。
```shell
* 1.向处理器添加越来越多的内核如四核和八核CPU。
* 2.发明了超线程技术。
* 3.为处理器添加了更多缓存以提高性能。
```
Tips : 一旦我们没有办法在硬件上一直取得突破,我们只能提高软件的性能或者说我们需要高性能的软件。
如上所述硬件制造商正在为处理器添加越来越多的内核以提高性能。所有数据中心都在这些处理器上运行更重要的是今天的应用程序使用多个微服务来维护数据库连接消息队列和维护缓存。因此开发的软件和编程语言应该可以轻松地支持并发性并且应该能够随着CPU核心数量的增加而可扩展。
**发展历史**
描述: 大多数现代编程语言如JavaPython等都来自90年代的单线程环境。虽然一些编程语言的框架在不断地提高多核资源使用效率例如 Java 的 Netty 等,但仍然需要开发人员花费大量的时间和精力搞懂这些框架的运行原理后才能熟练掌握。
- Go 于 2007年9月由于`罗伯特·格瑞史莫、罗勃·派克及肯·汤普逊于开始设计,[3]稍后伊恩·兰斯·泰勒Ian Lance Taylor、拉斯·考克斯Russ Cox`加入项目。
![WeiyiGeek.Go核心开发团队](assets/da92a01501b0356acdde8107417b0a067d23cf91.png@942w_459h_progressive.webp)
- Go 于 2009年11月正式宣布推出版本1.0在2012年3月发布之后Go广泛应用于Google的产品以及许多其他组织和开源项目。
- Go 于 2009年11月10日由Google发布推出成为开放源代码项目支持Linux、macOS、Windows等操作系统。2005 年 AMD 速龙发布第一款民用级多核处理器,所以当时多核处理器已经上市。
![WeiyiGeek.为现代软件工程而生的Go](assets/6d4bdcba8912f91f836f5f48691e2f0cb6437457.png@942w_479h_progressive.webp)
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) 不同于 JavaGo原生提供了关联数组也称为`哈希表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 语言
![WeiyiGeek.编译型的语言](assets/dbe8a06f8a3d61f2e167d7b3ee3c5ad49a1f8d86.png@942w_566h_progressive.webp)
由下图可以看出Go 语言在性能上更接近于 Java 语言,虽然在某些测试用例上不如经过多年优化的 Java 语言,但毕竟 Java 语言已经经历了多年的积累和优化。Go 语言在未来的版本中会通过不断的版本优化提高单核运行性能。
![WeiyiGeek.常见编程语言运行性能比较](assets/6a1c46098135c9607151fade0505268e2bbfacd1.png@942w_249h_progressive.webp)
数据来源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在知乎内部应用知乎全站重构
![WeiyiGeek.应用Go语言的公司](assets/13e14c6da60930aa4dad336ce26f83145c64476e.png@942w_261h_progressive.webp)
现在就开始你的Go语言学习之旅吧人生苦短lets 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` 可执行文件版本为例, 双击下载好的文件,然后按照下图的步骤安装即可。
![WeiyiGeek.Windows](assets/27fe8a5dd8aa47fa49b7a5db789310e2c545ffa8.png@942w_624h_progressive.webp)
**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
```
![WeiyiGeek.Go-Binary](assets/b83caffa0941d9b3c929e09be07098d5e8563960.png@906w_1031h_progressive.webp)
# 开发环境
描述: 由于本人习惯于使用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 则为安装成功。
```
![WeiyiGeek.Go开发依赖软件](assets/5c060ab80e0342858f4e36fceec46a776bc74f33.png@942w_773h_progressive.webp)
- 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": "将拼接的字符串返回给变接收量"
}
}
```
![WeiyiGeek.自动保存与代码片段快捷键](assets/4c3bdce2b26e8bc3baf4eb341161acd8edc0fcdd.png@942w_270h_progressive.webp)
- Step 6.把上面的代码按下图方式粘贴到配置文件中保存并关闭配置文件即可。然后我们打开一个go文件测试一下效果
GIF
![WeiyiGeek.代码片段快捷键效果](assets/205355dda9ee9e48b7c23c03ddbfa8b9d27c04ce.gif@1s.webp)
# 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`进行快速测试编写的程序。
![WeiyiGeek.VScode调试Go程序](assets/409d6915ad09c30f3dbfbf4c4b78931649a1a8c0.png@942w_566h_progressive.webp)
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 SystemVCS。常用如Git/Svn`来管理我们的项目代码时,我们只需要添加`$GOPATH/src`目录的源代码即可, bin 和 pkg 目录的内容无需版本控制。
通常来讲`GOPATH`目标下文件目录组织架构的设置常常有以下三种:
# (1)适合个人开发者
描述: 我们知道源代码都是存放在GOPATH的src目录下那我们可以按照下图来组织我们的代码。
![WeiyiGeek.适合个人开发者](assets/e850cd44113c98ed6b73060c17c415810c6fa1f1.png@930w_558h_progressive.webp)适合个人开发者
# (2)适合企业开发场景
描述: 此种目录结构设置更适合企业开发环境,以代码仓库为前缀并以公司内部组织架构为基准,其次是项目名称,最后是各个模块开发的名称。
![WeiyiGeek.适合企业开发场景](assets/8e2305d5dc1de204fa366cac4abac9dd9d674016.png@942w_410h_progressive.webp)适合企业开发场景
# (3)目前流行的项目结构
描述: Go语言中也是通过包来组织代码文件我们可以引用别人的包也可以发布自己的包但是为了防止不同包的项目名冲突我们通常使用顶级域名来作为包名的前缀这样就不担心项目名冲突的问题了。
因为不是每个个人开发者都拥有自己的顶级域名所以目前流行的方式是使用个人的github用户名来区分不同的包。
![WeiyiGeek.目前流行的项目结构](assets/6430f2bbc96a68ddeb83b826ab9fc5fd41f368d7.png@942w_452h_progressive.webp)目前流行的项目结构
- 举例说明: 张三和李四都有一个名叫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`。
总结说明: 后续我们的开发学习示例基本按照第三种项目结构进行。