Go基础|第1章:准备开发环境

  • 原创
  • Madman
  • /
  • /
  • 0
  • 1221 次阅读

Golang.jpg

Synopsis: 工欲善其事,必先利其器。本文介绍如何在 Windows 或 Linux 系统中安装 Go,并使用 Go Modules 包管理器来解决第三方依赖包的问题。如果你启用了 Go Modules 的情况下,那么可以通过 GOPROXY 代理服务器来安装那些国内无法正常访问的第三方包

1. 安装 Go

Go 的 Github 项目地址为 https://github.com/golang/go ,官方网站 https://golang.org 在国内是访问不了的。如果你会 科学上网 的话,可以直接到其官网的 https://golang.org/dl/ 下载安装程序即可。如果你不会也没关系,因为国内已经有人把 Go 的官方网站做了镜像网站,比如 https://golang.google.cn/

1.1 Windows 安装 go1.13

如果你是 Win10 系统的话,下载 MSI 二进制程序包,比如 go1.13.1.windows-amd64.msi。双击后运行,依次点击下一步即可(默认安装在 C:\Go\ 位置)。安装完成后,会自动在 PATH 系统环境变量中追加 C:\Go\bin,所以我们按 Ctrl + R 打开 CMD 命令行窗口后,可以直接运行 go 命令了,比如查看 Go 的版本:

Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。

C:\Users\wangy>go version
go version go1.13 windows/amd64

另外,它还会自动添加 GOPATHGORPOXY 等相关环境变量:

C:\Users\wangy>go env
...
set GOOS=windows
set GOROOT=c:\go
set GOPATH=C:\Users\wangy\go
set GOPROXY=https://proxy.golang.org,direct
...

1.2 Linux 安装 go1.13

如果你想在 Linux 系统中安装 Go:

1. 下载与解压
# wget https://dl.google.com/go/go1.13.1.linux-amd64.tar.gz
# tar -xzf go1.13.1.linux-amd64.tar.gz -C /usr/local

2. 设置环境变量
# echo -e "export GOROOT=/usr/local/go" >> /etc/profile
# echo -e "export GOPATH=$HOME/go" >> /etc/profile
# source /etc/profile

# echo -e "export PATH=$GOPATH/bin:$GOROOT/bin:$PATH" >> /etc/profile
# source /etc/profile

3. 验证
# go version
# go env

2. 熟悉 Go 相关子命令

安装完 Go 之后,go 命令行工具提供了一系列 子命令,可以实现对源代码进行 编译(go build)安装(go install)运行(go run)下载第三方包(go get) 等操作:

build       compile packages and dependencies
clean       remove object files
env         print Go environment information
fix         run go tool fix on packages
fmt         run gofmt on package sources
generate    generate Go files by processing source
get         download and install packages and dependencies
install     compile and install packages and dependencies
list        list packages
run         compile and run Go program
test        test packages
tool        run specified go tool
version     print Go version
vet         run go tool vet on packages

更加详细的 go 命令使用方法,请参考: https://golang.google.cn/cmd/go/

3. 测试你的安装

假设我们准备把 Go 源代码放在 D:\MyCode 目录下,那么我们在此目录下创建 main.go 文件:

package main

import "fmt"

func main() {
    fmt.Printf("Welcome to madmalls.com\n")
}

然后在 CMD 中运行:

D:\MyCode>go run main.go
Welcome to madmalls.com

Go 的官方库保存在 %GOROOT%\src 目录中,比如 C:\Go\src。所以,fmt 包的目录为 C:\Go\src\fmt\

4. Go Modules 包管理器

从 Go 1.11 版本开始,就可以通过设置 GO111MODULE=on 环境变量来启用 Go Modules 管理第三方依赖包,而从 Go 1.13 版本开始,默认已经启用了 Go Modules

假设我们要使用 Gin 框架来写一个 Web REST API 服务,项目的目录为 D:\MyCode\gin-rest-api,然后在此目录下创建 app.go 文件:

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}

直接运行时,会报错:

D:\MyCode\gin-rest-api>go run app.go
app.go:3:8: cannot find package "github.com/gin-gonic/gin" in any of:
        c:\go\src\github.com\gin-gonic\gin (from $GOROOT)
        C:\Users\wangy\go\src\github.com\gin-gonic\gin (from $GOPATH)

因为它需要第三方依赖包 gin,虽然我们可以通过 go get -u -v github.com/gin-gonic/gin 来手动下载它,但是你试想一下,如果后续你把这份 Go 源代码分享给其它人,他不知道你安装了哪些第三方依赖包,而 Go Modules 就是来解决这个问题的(他只需要执行 go mod tidy 即可)

4.1 go mod init

首先需要在项目的目录中运行 go mod init 命令进行初始化

注意: Go 官方提供的标准库中的包都有指定的短路径,比如 fmtnet/http,如果将来你自己开发了一个库也叫 fmt,就会与标准库冲突。所以,我们需要一个唯一的 基本路径。现在很多人都喜欢将代码开源到 Github 中,所以结合我们的用户名,这就是一个唯一的基本路径,比如我的 Github 用户名是 wangy8961,那么我可以使用类似 github.com/wangy8961/gin-rest-api 这样的格式来为项目命名:

D:\MyCode\gin-rest-api>go mod init github.com/wangy8961/gin-rest-api
go: creating new go.mod: module github.com/wangy8961/gin-rest-api

D:\MyCode\gin-rest-api>dir
2019/10/13  13:22               254 app.go
2019/10/13  14:50                50 go.mod

执行上述命令后,会自动生成 go.mod 文件,此时它的内容如下:

module github.com/wangy8961/gin-rest-api

go 1.13

然后,你再执行 go rungo build 命令时,Go Modules 会自动帮你查找依赖并下载到本地,非常方便!

D:\MyCode\gin-rest-api>go run app.go
go: finding github.com/gin-gonic/gin v1.4.0
go: downloading github.com/gin-gonic/gin v1.4.0
go: extracting github.com/gin-gonic/gin v1.4.0
go: downloading gopkg.in/yaml.v2 v2.2.2
go: downloading github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: downloading gopkg.in/go-playground/validator.v8 v8.18.2
go: downloading github.com/ugorji/go v1.1.4
go: extracting gopkg.in/yaml.v2 v2.2.2
go: downloading github.com/golang/protobuf v1.3.1
go: extracting gopkg.in/go-playground/validator.v8 v8.18.2
go: extracting github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: downloading github.com/mattn/go-isatty v0.0.7
go: extracting github.com/ugorji/go v1.1.4
go: extracting github.com/mattn/go-isatty v0.0.7
go: extracting github.com/golang/protobuf v1.3.1
go: finding github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3
go: finding github.com/golang/protobuf v1.3.1
go: finding github.com/ugorji/go v1.1.4
go: finding gopkg.in/go-playground/validator.v8 v8.18.2
go: finding gopkg.in/yaml.v2 v2.2.2
go: finding github.com/mattn/go-isatty v0.0.7
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

此时你再查看 go.mod 文件的内容:

module github.com/wangy8961/gin-rest-api

go 1.13

require github.com/gin-gonic/gin v1.4.0 // indirect

同时还会生成 go.sum 文件,它包含了各依赖包的版本控制信息。第三方依赖包下载后被保存在 %GOPATH%\pkg\mod 目录中,比如 C:\Users\wangy\go\pkg\mod

4.2 go mod tidy

如果你将 Go 源代码分享给其它人,只需要同时包含 go.modgo.sum 文件就行,对方执行 go mod tidy 就会自动拉取所需要的第三方依赖

5. GOPROXY 代理安装 golang.org/x/*

有一些第三方包,比如 golang.org/x/sysgolang.org/x/net 等在国内无法访问,假设我们写的 practice_map.go 代码需要依赖 golang.org/x/tour

package main

import (
    "golang.org/x/tour/wc"
    "strings"
)

func WordCount(s string) map[string]int {
    m := make(map[string]int)
    for _, word := range strings.Fields(s) {
        if count, ok := m[word]; ok {
            m[word] = count + 1
        } else {
            m[word] = 1
        }
    }
    return m
}

func main() {
    wc.Test(WordCount)
}

如果没有使用 Go Modules 管理依赖包时,只能 科学上网 后用 go get -u -v golang.org/x/tour 进行安装 或者git 去克隆 https://github.com/golang 上对应镜像包(比如 git clone https://github.com/golang/tour.git

而 Google 官方在发布 Go Modules 功能时还发布了 Module proxy protocol 协议,如果用户启用了 Go Modules 来管理依赖包(项目目录中有 go.mod 文件),那么只需要通过 GOPROXY 指定用户能够访问的代理服务器(实现了上述协议)即可,当 Go Modules 要下载相应的第三方依赖包时,会自动通过此代理服务器去获取依赖包

但是,安装 Go 后默认的 GOPROXY 环境变量指定 https://proxy.golang.org 代理服务器在国内也是被墙了的:

1. 默认的代理国内访问不了
D:\MyCode\go-basic>go env
...
set GOPROXY=https://proxy.golang.org,direct

2. 此时,就算是 Go Modules 也无法成功下载 golang.org/x/tour 依赖包
D:\MyCode\go-basic>go run practice_map.go
build command-line-arguments: cannot load golang.org/x/tour/wc: module golang.org/x/tour/wc: Get https://proxy.golang.org/golang.org/x/tour/wc/@v/list: dial tcp 172.217.24.17:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

幸好,像 https://goproxy.cn(由七牛云运行,支持 CDN 加速) 和 https://goproxy.io 这两个同样实现了 Module proxy protocol 协议的代理服务器在国内是能够访问的,所以我们只需要修改一下 GORPOXY 的值即可:

1. 设置成国内能访问的代理服务器
D:\MyCode\go-basic>go env -w GOPROXY=https://goproxy.cn,direct

2. 查看修改后的值
D:\MyCode\go-basic>go env
...
set GOPROXY=https://goproxy.cn,direct

3. 此时通过 Go Modules 就能成功下载 golang.org/x/tour 依赖包了
D:\MyCode\go-basic>go run practice_map.go
go: finding golang.org/x/tour latest
go: downloading golang.org/x/tour v0.0.0-20191002171047-6bb846ce41cd
go: extracting golang.org/x/tour v0.0.0-20191002171047-6bb846ce41cd
PASS
 f("I am learning Go!") =
  map[string]int{"Go!":1, "I":1, "am":1, "learning":1}
PASS
 f("The quick brown fox jumped over the lazy dog.") =
  map[string]int{"The":1, "brown":1, "dog.":1, "fox":1, "jumped":1, "lazy":1, "over":1, "quick":1, "the":1}
PASS
 f("I ate a donut. Then I ate another donut.") =
  map[string]int{"I":2, "Then":1, "a":1, "another":1, "ate":2, "donut.":2}
PASS
 f("A man a plan a canal panama.") =
  map[string]int{"A":1, "a":2, "canal":1, "man":1, "panama.":1, "plan":1}

注意: 如果你使用 Goland IDE 进行代码编辑的话,还需要在 FileSettins... 中设置 proxy:

Goland 设置 GOPROXY.png

6. 编辑器插件和IDE

  • vim: vim-go plugin provides Go programming language support
  • Visual Studio Code: Go extension provides support for the Go programming language
  • GoLand: GoLand is distributed either as a standalone IDE or as a plugin for IntelliJ IDEA Ultimate
  • Atom: Go-Plus is an Atom package that provides enhanced Go support

7. Go Playground

Go 官方提供了一个在线运行、分享 Go 语言代码的平台 Go Playground,国内访问不了,可以根据 https://github.com/golang/playground 自行搭建

8. 入门必读

A Tour of Go 是 Go 官方出品的交互式教程,包含了 Go 编程基础知识的许多示例程序,浅显易懂。如果英语水平可以的话建议直接看原版英文的,毕竟中文翻译后有些词不达意

Effective Go 教你如何写出优雅的 Go 风格代码:

未经允许不得转载: LIFE & SHARE - 王颜公子 » Go基础|第1章:准备开发环境

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.