Go 编程 | 连载 21 - Go Modules 和 Package

简介: Go 编程 | 连载 21 - Go Modules 和 Package

一、GOPATH 与 Go Modules

GOPATH 开发模式

GOPATH 是 Go 语言中使用的一个环境变量,它使用绝对路径提供项目的共工作目录,GOPATH 适合处理大量 Go 语言源码、多个包组合而成的复杂工程。

在命令行中输入 go env 可以查看 Go 的环境变量相关信息

image.png

Go 在 1.12 版本之前没有包管理的概念,所有的代码都保存在 GOPATH 的 src 目录下。

经过 go buildgo install 或者 go get 指令后,会将产生的二进制可执行文件存放在 GOPATH 的 bin 目录下,生成的中间缓存文件会保存在 GOPATH 的 pkg 目录下。

Go Modules 开发模式

Go Modules 是 Go 1.11 版本之后官方推出的版本管理工具,并且从 Go 1.13 版本开始为默认的依赖管理工具。

Go 1.11 版本开始在 GOPATH 以外的目录使用 go.mod 创建项目。使用 Go Module 管理的项目根目录中会包含 go.mod 文件,该文件为项目的依赖。

以一个 Gin Web 项目的 go.mod 为例,包含的依赖如下:

module gin-quickstart
go 1.18
require (
   github.com/gin-contrib/sse v0.1.0 // indirect
   github.com/gin-gonic/gin v1.8.1 // indirect
   github.com/go-playground/locales v0.14.0 // indirect
   github.com/go-playground/universal-translator v0.18.0 // indirect
   github.com/go-playground/validator/v10 v10.11.0 // indirect
   github.com/goccy/go-json v0.9.10 // indirect
   github.com/json-iterator/go v1.1.12 // indirect
   github.com/leodido/go-urn v1.2.1 // indirect
   github.com/mattn/go-isatty v0.0.14 // indirect
   github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
   github.com/modern-go/reflect2 v1.0.2 // indirect
   github.com/pelletier/go-toml/v2 v2.0.2 // indirect
   github.com/ugorji/go/codec v1.2.7 // indirect
   golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
   golang.org/x/net v0.0.0-20220726230323-06994584191e // indirect
   golang.org/x/sys v0.0.0-20220727055044-e65921a090b8 // indirect
   golang.org/x/text v0.3.7 // indirect
   google.golang.org/protobuf v1.28.0 // indirect
   gopkg.in/yaml.v2 v2.4.0 // indirect
)
复制代码

其中 module 是用来定义包名,require 表示定义依赖包及版本,而 indirect 表示间接引用。

go mod 常用命令如下:

  • go mod download:下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录)
  • go mod edit:编辑go.mod文件
  • go mod graph:打印模块依赖图
  • go mod init:初始化当前文件夹, 创建go.mod文件
  • go mod tidy:增加缺少的module,删除无用的module
  • go mod vendor:将依赖复制到vendor下
  • go mod verify:校验依赖
  • go mod why:解释为什么需要依赖

使用 Go Modules 创建项目有两种方式,第一种方式是可以直接使用 Goland IDE 选择 Go Modules 模式创建项目。

image.png

也可以直接创建一个文件夹作为工作目录,进入文件夹之后使用 go mod init 工作目录名 来初始化,该命令会生成一个 go.mod 文件来管理项目相关依赖。

二、Go Package

包(Package)是多个 Go 源码的集合,是一种高级代码复用方案,Go 语言默认提供了很多包,如 fmtosio 等。代码中用到相关包会自动导入。

同变量一样,如果包导入了但是没有使用,IDE 会有报错提示。

包具有如下特性:

  • 一个目录下的同级文件归属一个包
  • 包名可以与其目录不同名
  • 包名为 main 的包为应用程序的入口包,编译源码没有 main 包时将无法编译输出可执行文件。

Go 语言区分到小写,只有变量名或者结构体及结构体字段首字母大写才可以被其他包引用。

Go 中包的导入分为单行和多行导入

import "package1"
import "package2"
复制代码
import (
    "package1"
    "package2"
)
复制代码

新建一个 zulu package,首先在该 package 下新建一个 main 文件,接着再新建一个 operator package,在 operator  package 下添加两个 add.go 和 sub.go 文件,zulu package 目录结构如下:

.
├── go.mod
├── main.go
└── operator
    ├── add.go
    ├── go.mod
    └── sub.go
1 directory, 5 files
复制代码

其中 add.go 和 sub.go 文件的内容如下

// filename: add.go
package operator
func Add(x, y int) int {
   return x + y
}
func addWithlowerCase(x, y int) int {
   return x + y
}
复制代码
// filename:sub.go
package operator
func Sub(x, y int) int {
   return x - y
}
复制代码

然后我们可以在 main 文件中调用 operator 包下的函数

package main
import "zulu/operator"
func main() {
   operator.Add(1, 2)
   operator.Sub(2, 1)
   // Unexported function 'addWithlowerCase' usage
   // operator.addWithlowerCase(1, 2)
}
复制代码

如果运行出现 package xxx is not in GOROOT (/usr/local/go/src/xxx) 报错,解决此问题首先要确保是在 Go Mod 模式下进行开发的,既要在 package 目录下执行 go mod init packageName 并且设置 Go 环境变量 GO111MODULE="on"

export GO111MODULE="on"
复制代码

Go Package 的导入可以支持给包名起别名

package main
import (
   // 起别名
   ope "zulu/operator"
)
func main(){
   // 使用别名调用
   ope.Add(1, 2)
}
复制代码

如果导入包不使用,为了避免报错可以用 _ 命名

package main
import (
    // 别名为 _
    _"zulu/operator"
)
func main(){
}


相关文章
|
28天前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
29 1
|
1月前
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
41 7
|
1月前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
2月前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
53 7
|
2月前
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。
|
3月前
|
存储 缓存 Go
go语言编程系列(五)
go语言编程系列(五)
|
3月前
|
搜索推荐 Java 编译器
go语言编程系列(四)
go语言编程系列(四)
|
3月前
|
存储 JSON 安全
go语言编程系列(七)
go语言编程系列(七)
|
3月前
|
存储 安全 编译器
go语言编程系列(六)
go语言编程系列(六)
|
3月前
|
自然语言处理 Java 测试技术
go语言编程系列(二)
go语言编程系列(二)