2

Golang环境变量、编译和模块

 2 years ago
source link: https://lianpf.github.io/posts/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/golang%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F_%E7%BC%96%E8%AF%91_%E6%A8%A1%E5%9D%97/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

介绍包的相关概念以及使用方法…


golang中,所有源文件都属于一个包,golang的包具有以下特性:

  • 包可以被其他包引用
  • 每个golang程序只有一个main
  • 包的主要用途是提高代码的可复用性

一、GOPATH环境变量

1.什么是GOPATH

golang包的使用依赖一个重要的环境变量:GOPATH,无论是自己的代码还是第三方代码,都以GOPATH作为工作目录和一套完整的工程目录规则。GOPATH目录约定有三个子目录,主要用于:

  • src:存放各种包源代码,src里的一个目录就是一个包
  • pkg:存放编译源代码后的类库
  • bin:存放编译源代码后的可执行程序

GOPATH允许多个目录,设置多个目录时,需要使用环境变量分隔符来区分。Unix/Linux的环境变量分隔符是英文输入法下的冒号:windows的环境变量分隔符是英文分号;

使用GOPATH时,golang会在以下目录中搜索包:

  1. GOROOT/src:该目录保存了Go标准库里代码
  2. GOPATH/src:该目录保存了应用自身的代码和第三方依赖的代码

2.设置GOPATH环境变量

Unix/Linux中,使用sudo vim/etc/profile打开系统profile文件,并追加以下内容设置GOPATH环境变量,同时设置GO111MODULE为关闭状态,GO111MODULE环境变量我们在文章中后面部分说明

export GOPATH=/Users/pan/go # 把自己的golang项目目录作为GOPATH的变量
export GO111MODULE=off # 关闭golang 11.1 版本以后的模块功能

使用source /etc/profile命令重新加载环境变量

3.包的使用

3.1 main包与包的引入

  1. 引入系统包

我们可以通过package关键字定义一个包,使用import引入其他包,如果需要引入多个包,可以将各个包声明在括号内

package main

import (
	// 引入系统的包
	"fmt"
)

func main() {
	// 调用系统包的函数
	fmt.Println("Hello World")
}

在以上代码中,我们通过main关键字定义了main包,主函数main必须位于main包下。程序中引入了fmt包,该包由golang本身提供。

  1. 引入自定义包

我们在GOPATH/src目录下创建两个文件: 文件1,库文件位于jkdev.cn/test/mypkg/lib.go,添加以下代码

package mypkg

import "fmt"

func TestFunc() {
	fmt.Println("call testFunc")
}

文件2,主文件jkdev.cn/test/main.go,添加以下代码

package main

// 引入自定义包
import "jkdev.cn/test/mypkg"

func main() {
	// 调用自定义包的函数
	mypkg.TestFunc()
}

自定义的包由我们自己定义,但要注意的是,一个目录对应一个包,同时,包名应当和目录名一致。引入包时,路径相对应GOPATH/src,我们可以根据自己的程序的功能模块划分不同的包

3.2 包的作用域

  • 包内:在同一个包内定义的函数、变量、常量、结构体,可以被包内的所有其他代码任意访问,它们属于包内公开。
  • 包外:如果函数、变量、常量、结构体位于不同的包下,如果将它们的首字母使用大写标识,表示它们是公开访问的。对于结构体字段。如果想要在包外进行访问,还要让结构体字段变量名使用首字母大写。

golanggo build命令主要用于编译代码。在包的编译过程中,若有必要,会同时编译与之相关联的包。

假设我们的设置GOPATH/Users/pan/go,我们在GOPATH之下的src创建创建代码test目录,并添加lib.gomain.go两个文件。此时,源文件相对于GOPATH的路径如下。接下来我们对这两个go源文件进行编译

go  GOPATH目录
├─src                  源码目录
│  ├─test              项目目录
│     ├─lib.go         公共函数文件
│     └─main.go        主函数文件

lib.go代码如下:

package main

import "fmt"

func testFunc() {
	fmt.Println("call testFunc")
}

main.go代码如下:

package main

func main() {
	testFunc()
}

示例中的两个源文件都属于main包,所以在main.go文件中能正常引入lib.go文件

1.go build

1.1 无参数编译

无参数编译不依赖GOPATH,需要在源码目录下进行编译

# 进入源码目录
cd ~/go/src/test
# 编译代码
go build

我们还可以-o指定编译后输出的可执行文件的文件名,如下

go build -o main

1.2 go build 文件列表

使用“go build+文件列表”编译时,文件列表中的每个文件必须是同一个包的Go源码

# 进入源码目录
cd ~/go/src/test
# 编译
go build lib.go main.go

1.3 go build

包的路径相对于GOPATH,“go build+包”编译时,源文件需要存放在GOPATH/src下的路径,但是我们可以在任意有读写权限的目录执行编译命令,如下

# test 相对于GOPATH/src
go build test

2.go install

go build具有相似功能的是go install命令,go install用来生成库和工具并存放于GOPATH中。

  • 一是编译包文件(无main包),将编译后的包文件放到pkg目录下(GOPATH/pkg)。
  • 二是编译生成可执行文件(有main包),将可执行文件放到 bin目录(GOPATH/bin

3.go buildgo install 对比

  • 都能生成可执行文件
&包文件可执行文件目录
go build不能生成包文件生成可执行文件在当前目录下
go install可以生成包文件生成可执行文件在bin目录下($GOPATH/bin)

三、Go模块

golang在1.11版本引入Go Modules,也叫做Go模块,模块依赖于上文提到的GO111MODULE环境变量。它是golang官方提供的包管理工具,通过Go Modules,我们可以不必将项目放在GOPATH

1.GO111MODULE环境变量

用环境变量GO111MODULE设置开启或者关闭模块支持,它有三个可选值:offonauto,默认是auto

  • GO111MODULE=off:无模块支持,go会从GOPATH寻找包。
  • GO111MODULE=on:模块支持,根据go.mod文件下载依赖
  • GO111MODULE=auto:在$GOPATH/src外面且项目根目录有go.mod文件时,自动开启模块支持

在使用模块的时候,GOPATH是无意义的,但golang还是会把下载的依赖存储于GOPATH之下

2.使用go模块

使用Go Modules时,我们先将GO111MODULE设置为on或者autoGo ModulesGOPATH不同,不需要包含固定的三个字目录。一个空的源代码目录,只要初始化好go.mod文件,就可以定义一个Module。我们可以使用以下命令创建一个新的Module

# 创建一个空的工作目录
mkdir -p ~/Work/go/test
# 进入工作目录
cd ~/Work/go/test
# 初始化一个module
go mod init testmodule

我们可以看到自动生成的go.mod文件的内容如下

module testmodule

go 1.16

2.1 下载依赖

Go Modules会为我们进行包管理,并自动更新go.mod文件,如果需要引入新的依赖,我们只需要在终端执行go get 包名即可引入第三方包,如

go get github.com/satori/go.uuid

执行命令后,Go Modules会从我们在安装golang时设置的GOPROXY镜像仓库地址去下载对应的包,安装完成之后我们看到go.mod已经发生变化,如下

module testmodule

go 1.16

require github.com/satori/go.uuid v1.2.0 // indirect

我们也可以先编辑好go.mod文件,然后在终端使用go mod downloadgolang会自动帮我们下载依赖包到本地。如果我们需要引入多个包,将所有包名卸载括号内,如下代码

module testmodule

go 1.16

require (
	github.com/satori/go.uuid v1.2.0 // indirect
	gorm.io/gorm v1.21.11 // indirect
)

2.2 更新依赖关系

使用go mod tidy更新依赖关系,该命令拉取缺少的模块,移除不用的模块。Go Modules可以轻易地进行一个包的依赖管理和版本控制,go buildgo install将自动使用go.mod中的依赖关系,减少了GOPATH管理时的复杂性


最后, 希望大家早日实现:成为前端高手的伟大梦想!
欢迎交流~

微信公众号

本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK