深入解析:Go基础:模块化管理为什么能够提升研发效能?

news/2025/9/27 14:18:13/文章来源:https://www.cnblogs.com/slgkaifa/p/19115074

深入解析:Go基础:模块化管理为什么能够提升研发效能?

文章目录

    • 一、Go语言中的包
      • 1.1 什么是包
      • 1.2 使用包
      • 1.3 作用域
      • 1.4 自定义包
      • 1.5 init 函数
    • 二、Go 语言中的模块
      • 2.1 go mod
      • 2.2 使用第三方模块
    • 三、总结

一、Go语言中的包

Go语言通过包(package)来组织代码,每个Go文件都属于一个包,包名通常与文件所在目录名一致。包的主要作用是封装功能,避免命名冲突,提高代码复用性。

1.1 什么是包

在业务非常简单的时候,你甚至可以把代码写到一个 Go 文件中。但随着业务逐渐复杂,你会发现,如果代码都放在一个 Go 文件中,会变得难以维护,这时候你就需要抽取代码,把相同业务的代码放在一个目录中。在 Go 语言中,这个目录叫作包。

在 Go 语言中,一个包是通过package 关键字定义的,最常见的就是main 包,它的定义如下所示:

package main

此外,前面章节演示示例经常使用到的 fmt 包,也是通过 package 关键字声明的。

一个包就是一个独立的空间,你可以在这个包里定义函数、结构体等。这时,我们认为这些函数、结构体是属于这个包的。

1.2 使用包

如果你想使用一个包里的函数或者结构体,就需要先导入这个包,才能使用,比如常用的 fmt包,代码示例如下所示。

package main
import "fmt"
func main() {
fmt.Println("先导入fmt包,才能使用")
}

要导入一个包,需要使用 import 关键字;如果需要同时导入多个包,则可以使用小括号,示例代码如下所示。

import (
"fmt"
"os"
)

从以上示例可以看到,该示例导入了 fmt 和 os 这两个包,使用了小括号,每一行写了一个要导入的包。

1.3 作用域

讲到了包之间的导入和使用,就不得不提作用域这个概念,因为只有满足作用域的函数才可以被调用。

  • 在Java 语言中,通过 public、private 这些修饰符修饰一个类的作用域;
  • 但是在Go 语言中,并没有这样的作用域修饰符,它是通过首字母是否大写来区分的,这同时也体现了 Go 语言的简洁。

如上述示例中 fmt 包中的Println 函数:

  • 它的首字母就是大写的 P,所以该函数才可以在 main 包中使用;
  • 如果 Println 函数的首字母是小写的 p,那么它只能在 fmt 包中被使用,不能跨包使用。

这里总结下 Go 语言的作用域:

  • Go 语言中,所有的定义,比如函数、变量、结构体等,如果首字母是大写,那么就可以被其他包使用;
  • 反之,如果首字母是小写的,就只能在同一个包内使用。

1.4 自定义包

你也可以自定义自己的包,通过包的方式把相同业务、相同职责的代码放在一起。比如你有一个 util 包,用于存放一些常用的工具函数,项目结构如下所示:

xxx
├── main.go
└── util
└── string.go

在 Go 语言中,一个包对应一个文件夹,上面的项目结构示例也验证了这一点。在这个示例中,有一个 util 文件夹,它里面有一个 string.go 文件,这个 Go 语言文件就属于 util 包,它的包定义如下所示:
xxx/util/string.go

package util

可以看到,Go 语言中的包是代码的一种组织形式,通过包把相同业务或者相同职责的代码放在一起。通过包对代码进行归类,便于代码维护以及被其他包调用,提高团队协作效率。

1.5 init 函数

除了 main 这个特殊的函数外,Go 语言还有一个特殊的函数——init,通过它可以实现包级别的一些初始化操作。init 函数没有返回值,也没有参数,它先于 main 函数执行,代码如下所示:

func init() {
fmt.Println("init in main.go ")
}

一个包中可以有多个 init 函数,但是它们的执行顺序并不确定,所以如果你定义了多个 init 函数的话,要确保它们是相互独立的,一定不要有顺序上的依赖。

那么 init 函数作用是什么呢? 其实就是在导入一个包时,可以对这个包做一些必要的初始化操作,比如数据库连接和一些数据的检查,确保我们可以正确地使用这个包。

二、Go 语言中的模块

如果包是比较低级的代码组织形式的话,那么模块就是更高级别的,在 Go 语言中,一个模块可以包含很多个包,所以模块是相关的包的集合。在 Go 语言中:

  • 一个模块通常是一个项目,比如这个专栏实例中使用的 gotour 项目;
  • 也可以是一个框架,比如常用的 Web 框架 gin。

2.1 go mod

Go 语言为我们提供了 go mod 命令来创建一个模块(项目),比如要创建一个 gotour 模块,你可以通过如下命令实现:

➜ go mod init gotour
go: creating new go.mod: module gotour

运行这一命令后,你会看到已经创建好一个名字为 gotour 的文件夹,里面有一个 go.mod 文件,它里面的内容如下所示:

module gotour
go 1.25

第一句是该项目的模块名,也就是 gotour;第二句表示要编译该模块至少需要Go 1.15 版本的 SDK。

小提示:模块名最好是以自己的域名开头,比如 xxxx.com/gotour,这样就可以很大程度上保证模块名的唯一,不至于和其他模块重名。

2.2 使用第三方模块

模块化为什么可以提高开发效率?最重要的原因就是复用了现有的模块,Go 语言也不例外。比如你可以把项目中的公共代码抽取为一个模块,这样就可以供其他项目使用,不用再重复开发;同理,在 Github 上也有很多开源的 Go 语言项目,它们都是一个个独立的模块,也可以被我们直接使用,提高我们的开发效率,比如 Web 框架gin: https://gin-gonic.com/zh-cn/。

众所周知,在使用第三方模块之前,需要先设置下 Go 代理,也就是 GOPROXY,这样我们就可以获取到第三方模块了。

在这里我推荐 goproxy.io 这个代理,非常好用,速度也很快。要使用这个代理,需要进行如下代码设置:

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

打开终端,输入这一命令回车即可设置成功。

在实际的项目开发中,除了第三方模块外,还有我们自己开发的模块,放在了公司的 GitLab上,这时候就要把公司 Git 代码库的域名排除在 Go PROXY 之外,为此 Go 语言提供了GOPRIVATE 这个环境变量帮助我们达到目的。通过如下命令即可设置 GOPRIVATE:

# 设置不走 proxy 的私有仓库,多个用逗号相隔(可选)
go env -w GOPRIVATE=*.corp.example.com

以上域名只是一个示例,实际使用时你要改成自己公司私有仓库的域名。

一切都准备好就可以使用第三方的模块了,假设我们要使用 Gin 这个 Web 框架,首先需要安装它,通过如下命令即可安装 Gin 这个 Web 框架:

go get -u github.com/gin-gonic/gin

安装成功后,就可以像 Go 语言的标准包一样,通过 import 命令导入你的代码中使用它,代码如下所示:

package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
fmt.Println("先导入fmt包,才能使用")
r := gin.Default()
r.Run()
}

以上代码现在还无法编译通过,因为还没有同步 Gin 这个模块的依赖,也就是没有把它添加到go.mod 文件中。通过如下命令可以添加缺失的模块:

go mod tidy // 清理未使用的依赖

运行这一命令,就可以把缺失的模块添加进来,同时它也可以移除不再需要的模块。这时你再查看 go.mod 文件,会发现内容已经变成了这样:

module example.com/m
go 1.25.0
require github.com/gin-gonic/gin v1.11.0
require (
github.com/bytedance/gopkg v0.1.3 // indirect
github.com/bytedance/sonic v1.14.1 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // 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.2.4 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
go.uber.org/mock v0.6.0 // indirect
golang.org/x/arch v0.21.0 // indirect
golang.org/x/crypto v0.42.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/tools v0.37.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
)

所以我们不用手动去修改 go.mod 文件,通过 Go 语言的工具链比如 go mod tidy 命令,就可以帮助我们自动地维护、自动地添加或者修改 go.mod 的内容。

三、总结

在 Go 语言中,包是同一目录中,编译在一起的源文件的集合。包里面含有函数、类型、变量和常量,不同包之间的调用,必须要首字母大写才可以。

而模块又是相关的包的集合,它里面包含了很多为了实现该模块的包,并且还可以通过模块的方式,把已经完成的模块提供给其他项目(模块)使用,达到了代码复用、研发效率提高的目的。

所以对于你的项目(模块)来说,它具有 模块 ➡ 包 ➡ 函数类型 这样三层结构,同一个模块中,可以通过包组织代码,达到代码复用的目的;在不同模块中,就需要通过模块的引入,达到这个目的。

编程界有个谚语:不要重复造轮子,使用现成的轮子,可以提高开发效率,降低 Bug 率。Go 语言提供的模块、包这些能力,就可以很好地让我们使用现有的轮子,在多人协作开发中,更好地提高工作效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/919563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无锡网站定制宝塔面板怎么做自己的网站

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

2025黄鹤杯线上wp

2025黄鹤杯线上赛 Web Code <?php highlight_file(__FILE__); include("aid.php"); if(!(isset($_GET["input1"]) && isset($_GET["input2"]) && isset($_GET[&quo…

一条频率信道是什么?

一条频率信道是什么?无线信号的传输,依赖 “电磁波的频率变化” 来承载信息(如调幅 AM、调频 FM、数字调制 QPSK 等)。而任何承载信息的电磁波,都不可能只占用 “一个频率点” —— 它必然会 “占用一段连续的频率…

Dropout

Dropout(丢弃法)是一种在神经网络训练中广泛使用的正则化(Regularization)技术。它的主要作用是防止模型在训练集上过拟合(Overfitting),从而提高模型在未见过数据(测试集)上的泛化能力。Dropout 类的作用和工…

免费做的英文网站微信 小程序

作者 | 百度搜索用户体验中心 《Web设计指南》分为设计原则、基础规范两方面主要内容&#xff0c;同时会提供相应的实际案例及资源下载。关注OpenWeb开发者&#xff0c;回复“设计指南”&#xff0c;即可获取已发布资源。 设计原则之高级精致 简洁并不等于粗糙没有细节&#x…

经典排序算法深度解析 - 实践

经典排序算法深度解析 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

做图软件ps下载网站有哪些内容成都的网站设计公司价格

参考&#xff1a;https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html 在GIS&#xff08;地理信息管理系统&#xff09;中&#xff0c;判断一个坐标是否在多边形内部是个经常要遇到的问题。乍听起来还挺复杂。根据W. Randolph Franklin 提出的PNPoly算法&#xff0c;…

深入解析:阿里云推出全球首个全模态AI模型Qwen3-Omni,实现文本、图像、音视频端到端处理

深入解析:阿里云推出全球首个全模态AI模型Qwen3-Omni,实现文本、图像、音视频端到端处理2025-09-27 13:58 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !importan…

第十篇:模块一总结与答疑:如何养成良好的编码习惯和调试思维 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Java网络编程(七):NIO实战构建高性能Socket服务器 - 实践

Java网络编程(七):NIO实战构建高性能Socket服务器 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

完整教程:【大模型理论篇】用于时间序列预测的纯解码器基础模型TimesFM-2.5

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

做卡盟网站教程wordpress 翻页

输入&#xff1a;df_Grp&#xff0c;类型是pandas.core.groupby.generic.DataFrameGroupBy 我们先来学习一下如何将分组后的其中一个分组给转换成DataFrame类型&#xff1a; tmp dict(list(df_Grp)) tmpname[] tmpname [i for i,j in df_Grp] #下面这行代码其实就转化成Dat…

Unigine整合Myra UI Library全纪录(3):整合与优化

MyraIntegration 当Texture2DManager,MyraRenderer和MyraPlatform都实现了之后,就可以将它们整合起来了。 首先,IMyraPlatform.Renderer返回实现好的MyraRenderer,而IMyraRenderer.TextureManager则返回实现好的Te…

MOS管 SI2302 KX2302 集成上下拉电阻,优化线路电路,降低物料成本

MOS管 SI2302 KX2302 集成上下拉电阻,优化线路电路,降低物料成本20VDS/+10VGSN沟道增强型MOSFET 功能VDS=20伏 RDS(ON)=64.1MQ(MAX.)@VGS=10V,ID=3A RDS(ON)=80.2MQ(MAX.)@VGS=4.5VID=3A EXCELLENT GATE CHARGEXRDS…

企业网站建设预算地方门户网站怎么赚钱

信号&#xff1a;事件 槽&#xff1a;事件处理函数 信号与槽&#xff08;Signal & Slot&#xff09;是 Qt 编程的基础&#xff0c;也是 Qt 的一大创新。因为有了信号与槽的编程机制&#xff0c;在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。 信号&#xff0…

Tita 项目经营一体化建筑业企业解决方案

一、建筑行业项目经营管理痛点剖析 (一)项目目标与企业战略脱节 建筑企业承接项目众多,各项目目标常孤立制定,与企业长期战略关联不紧密。例如企业战略聚焦绿色建筑领域拓展,某新建住宅项目却未将绿色环保施工指标…

CD78.【C++ Dev】以AVL任务的bug讲讲调试技巧

CD78.【C++ Dev】以AVL任务的bug讲讲调试技巧pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

网站建设 落地页搭建网站需要的软件下载

1.vim输入中文乱码 在/etc/vimrc最下面输入以下代码 set fileencodingsutf-8,gb2312,gbk,gb18030 set termencodingutf-8 set fileformatsunix set encodingprc 2.vim复制的时候如果有#号&#xff0c;下面的代码开头都会有#号 在编辑模式输入:set paste 再进行粘贴即可 3…

怎样做网站公司做百度推广的业务员电话

kubeadm安装k8s1.25版本集群步骤 环境说明实验环境规划集群搭建规划 初始化安装k8s集群的实验环境安装虚拟机更新yum源和操作系统配置机器主机名配置主机hosts文件&#xff0c;相互之间通过主机名互相访问配置主机之间无密码登录关闭交换分区swap&#xff0c;提升性能修改机器内…

登封网站建设公司设备网站模板

一、类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。但是空类中并不是真的什么都没有&#xff0c;任何类在什么都不写的时候&#xff0c;编译器会自动生成以下 6 个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成…