02 go语言(golang) - 包和模块

devtools/2024/10/15 4:55:02/

包(package)

在Go语言中,包(package)是一种封装代码的方式,用于组织和重用代码。包可以被看作是一个功能模块,它可以包含函数、变量、类型(如结构体和接口)以及其他包。使用包可以帮助开发者管理大型项目的复杂性,并促进代码的模块化和可维护性。

包的基本概念

  1. 定义

    • 每个Go文件都属于一个包,且文件中的第一行非注释代码应声明该文件所属的包。
    • 例如:package main 表示该文件属于 main 包。
  2. 导入

    • 如果你想使用其他包中定义的公共标识符(如函数、类型等),需要先导入这个包。
    • 使用 import 语句来导入需要的包。

    例如:import "fmt" 导入标准库中的 fmt

    // 导入一个包
    import "awesomeProject/test"// 导入多个包
    import "awesomeProject/test"
    import "fmt"// 导入多个包
    import ("awesomeProject/test""fmt"
    )
    
  3. 主程序入口

    • Go程序由一个名为 main 的特殊包开始执行,这个名为 main() 的函数是每个可执行程序必需的起点。
    • 只有名为 main 的包可以编译成一个可执行文件。
  4. 路径

    • 导入语句中使用字符串指定要导入的包路径。这些路径相对于 $GOPATH/src 或者 Go模块内部目录结构来解析。
  5. 初始化顺序

    • 包级变量按声明顺序初始化。
    • 每个包可以有一个或多个init函数,这些函数在所有变量声明后自动调用,并且在任何其他代码运行之前完成设置。
  6. 可见性:

    • 在Go中,默认情况下,在同一软件内部所有处都能访问同一软件内部不同源码文件里定义并且首字母大写命名规则命名过后标识符(如类型、变量、常数或者函数)。如果首字母小写,则表示它仅对同一软件内部相同源码所在目录下其它源码而言是私有(private)属性或方法。

示例

假设我们有几个测试文件,结构目录:

awesomeProject/
├── go.mod
├── main.go
└── _01package/└── one.go└── two.go
└── _02package/└── three.go
  • one.go:
package mainimport "awesomeProject/_02package"func main() {println("one")// 注:包的导入是导入整个包(文件夹),而不是里面的文件,使用包名可以直接调用模块里面所有文件夹的函数// 同个包下,无需导入直接使用TwoFunc()twoFunc()// 不同包,需要导入_02package.ThreeFunc()// 小写的方法(函数)只在同个包内可见,不可在其他包中调用// _02package.threeFunc()}
  • two.go:
package mainimport "fmt"func TwoFunc() {fmt.Println("two...")
}func twoFunc() {fmt.Println("two...")
}
  • three.go
package _02packagefunc ThreeFunc() {println("three...")
}func threeFunc() {println("three...")
}

报错:Multiple packages in the directory

在Go语言中,一个目录下的所有文件必须属于同一个包。这是Go的一项约定,它有助于简化构建过程和包管理。当你在同一个目录下拥有属于不同包的文件时,就会遇到你描述的问题:“Multiple packages in the directory”。

解决方案

  1. 统一包名
    • 确保该目录下所有文件的第一行声明的包名相同。
    • 例如,如果你希望所有文件都属于main包,则每个文件都应该以package main开始。
  2. 分离到不同目录
    • 如果这些文件确实应该属于不同的包,则应将它们移动到不同的目录中。
    • 每个目录可以有自己独立的包名,并且可以通过导入路径来引用其他目录(即其他包)中定义的公共标识符。

确保单个目录内只含有单一类型Package是关键。这样做既符合Go语言设计原则也能避免类似上述多Package错误提示。如果功能模块之间需要交互作用, 可以通过适当地组织代码并利用import机制来实现跨packages调用。

模块(module)

Go模块(Go Modules)是Go语言的官方依赖管理系统,自Go 1.11版本引入,并在Go 1.13中成为默认的依赖管理方式。模块系统旨在解决包的版本控制和依赖问题,使得源代码更易于维护、分享和协作开发。

核心概念

  1. 模块(Module)

    • 模块是相关Go包的集合。它是一个独立单元,拥有自己的go.mod文件,在这个文件中声明了模块路径和其依赖项。
    • 模块路径通常是版本控制仓库的位置,如 github.com/username/projectname
  2. go.mod 文件

    • 这个文件位于模块根目录下,标识了该目录内容属于哪个模块。

    • 它列出了项目所需的所有依赖项及其正确版本。

    • 示例内容:

      module github.com/username/myprojectgo 1.15require (github.com/some/dependency v1.2.3golang.org/x/text v0.3.2
      )
      
  3. go.sum 文件

    • 当运行像 go buildgo test 这样会自动更新 go.mod 的命令时,会同时生成或更新一个名为 go.sum 的文件。
    • 这个文件包含特定依赖项内容的预期加密哈希值,用以确保项目所使用的每个外部模块不被篡改或意外更改。
  4. 版本控制

    • Go Modules支持语义化版本号(Semantic Versioning),例如:v0.1, v1, v2等。
    • 可以指定使用特定版本、最新发布版或者某一分支上最新提交。
  5. 代理服务器(Proxy Server):

    • Go提供了一个公共代理服务器(https://proxy.golang.org),用来缓存公共可访问模块的所有公开发布版本。
    • 使用代理可以提高构建速度、提供无法直接访问某些VCS服务时候需要下载代码包时候备选方案。

通过引入Modules机制, Go语言大大简化了跨环境工作流程中对第三方库管理需求处理过程。这不仅使得开发者能够更容易地管理大型项目中复杂且多变动态性强烈需求场景下各种软件包之间相互关系与影响情况,并且也有助于确保软件构建过程稳定性与安全性。

模块(第三方依赖)的使用

1、使用专门的网站,查到你需要的依赖以及版本号

  • pkg.go.dev:这是Go官方提供的包文档和索引网站。你可以在这里搜索可用的包,并查看其文档、版本和许可信息。
  • GitHub 或其他代码托管平台:许多开源Go项目都托管在GitHub上。通过关键词搜索或浏览相关组织/用户的仓库,你可以找到所需库。

2、在go.mod中导入,比如我找的date这个依赖

require github.com/Azure/go-autorest/autorest/date v0.3.0

3、在项目目录下执行命令下载安装依赖

➜ awesomeProject go get github.com/Azure/go-autorest/autorest/date
go: downloading github.com/Azure/go-autorest v14.2.0+incompatible
go: downloading github.com/Azure/go-autorest/autorest v0.11.29
➜ awesomeProject 

4、在代码中导入依赖并使用

package mainimport ("github.com/Azure/go-autorest/autorest/date"
)func main() {d, _ := date.ParseDate("2024-10-01")print(d.String())
}

总结异同点

  1. 包(Package)

    • 包是 Go 语言中代码组织的基本单位。一个包可以包含多个.go源文件,这些文件中的代码共享相同的包名。
    • 包用于将功能相关的代码组织在一起,并且可以通过导入语句(import)被其他包使用。
    • 包提供了一种封装机制,允许开发者将内部实现细节隐藏起来,只暴露出一部分接口(即公开的函数、变量、类型等)。
  2. 模块(Module)

    • 从 Go 1.11 版本开始,Go 引入了模块作为依赖管理和封装的单位,这是对传统包概念的扩展。
    • 一个模块通常对应一个项目或库,它包含了一组相关的包。模块拥有自己的依赖关系,并且可以跨项目共享。
    • 模块定义了一组版本化的包,这些包可以被其他模块导入。模块通过 go.mod 文件来管理依赖关系,这个文件记录了模块的依赖和版本信息。
    • 模块的使用简化了依赖管理,使得开发者可以更容易地构建、测试和共享代码。

http://www.ppmy.cn/devtools/125987.html

相关文章

利用TDM在vscode中运行c语言

1. 安装 VSCode 如果你还没有安装 VSCode,可以从 VSCode 官网 下载并安装。 2. 安装 C/C 扩展 打开 VSCode。点击左侧边栏的扩展图标(四个小方块组成的图标),或者按 Ctrl Shift X。在搜索框中输入 C/C,然后安装由…

Leetcode 数组中第 k 大的元素

使用最小堆 (min-heap) 来解决该问题 代码逻辑: 初始化最小堆并插入前 K 个元素: 首先,将数组的前 K 个元素插入到堆中。此时,堆的大小为 K,堆顶元素是这 K 个元素中最小的。 遍历剩余的数组元素: 对于数…

基于协同过滤的景区旅游可视化与景区推荐系统(自动爬虫,地点可换)

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍过程展示项目移植每文一语 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 本项目是一个综合性的旅游景区数据管理与分析推荐系统,集成了用…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论&…

UE4 材质学习笔记08(雨滴流淌着色器/雨水涟漪着色器)

一.雨滴流淌着色器 法线贴图在红色通道和绿色通道上,那是法线的X轴和Y轴,在蓝色通道中 我有个用于雨滴流淌的蒙版,在Alpha通道中,有个时间偏移蒙版。这些贴图都是可以在PS上制作做来的,雨滴流淌图可以直接用笔刷画出来…

2024年华为OD机试真题-空栈压数-Python-OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述: 向一个空栈压入…

安卓13usb触摸唤醒系统 android13触摸唤醒

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 android13在待机后,需要能够使用触摸屏去唤醒我们的系统,这就需要我们修改系统的相关配置了。 2.问题分析 对于这个问题,我们需要知道安卓的事件分发,通过事件分发,…

基于微信小程序的旅游拼团系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…