9.2 Go语言入门(包和导入)

Go语言入门(包和导入)

  • 目录
    • 一、包和导入
      • 1. 包(Package)
        • 1.1 包的定义
        • 1.2 包的作用
        • 1.3 main 包
        • 1.4 非 main 包
      • 2. 导入(Import)
        • 2.1 导入标准库
        • 2.2 导入第三方包
        • 2.3 导入本地包
        • 2.4 导入别名
        • 2.5 导入并调用初始化函数
      • 3. 包的初始化顺序
      • 4. 循环导入
      • 5. 包的可见性

目录

Go 语言(Golang)是一种静态类型、编译型语言,由 Google 开发,专注于简洁性、并发和高效性。

下面是 Go 语言的基础语法讲解和代码示例。


上一篇:Go语言入门(环境篇)


一、包和导入

在 Go 语言中,包(package)和导入(import)机制是其模块化设计的核心。这些机制允许代码组织、重用和管理依赖性。下面详细讲解包和导入的概念、使用方法及相关细节。

1. 包(Package)

1.1 包的定义

在 Go 中,每个源文件都必须属于一个包。包的声明使用 package 关键字,通常放在文件的第一行。包名决定了该文件所属的包。

package main
1.2 包的作用

包用于将相关的代码组织在一起,提供命名空间来避免命名冲突。标准库和第三方库都是以包的形式存在。

1.3 main 包

main 包是特殊的包,它定义了一个可独立运行的可执行程序。只有包含 main 函数的 main 包才能被编译为可执行文件。

package mainimport "fmt"func main() {fmt.Println("Hello, World!")
}
1.4 非 main 包

其他包(非 main 包)通常用于组织库代码,可以被其他包导入和使用。

package mathutilsfunc Add(a int, b int) int {return a + b
}

2. 导入(Import)

2.1 导入标准库

标准库是 Go 自带的一组包,可以直接导入和使用。例如,fmt 包用于格式化 I/O。

package mainimport ("fmt"
)func main() {fmt.Println("Hello, World!")
}
2.2 导入第三方包

使用 go get 工具从远程仓库获取第三方包。例如:

go get github.com/gin-gonic/gin

然后在代码中导入:

package mainimport ("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()
}
2.3 导入本地包

本地包可以使用相对或绝对路径导入。在项目目录下,结构可能如下:

project/
├── main.go
└── mathutils/└── add.go

main.go 文件导入 mathutils 包:

package mainimport ("fmt""project/mathutils"
)func main() {result := mathutils.Add(1, 2)fmt.Println(result)
}
2.4 导入别名

导入包时可以使用别名,这在包名过长或包名冲突时特别有用。

package mainimport (f "fmt"
)func main() {f.Println("Hello, World!")
}
2.5 导入并调用初始化函数

如果只想导入包并调用其初始化函数而不使用其中的任何导出函数,可以使用空白标识符 _

package mainimport (_ "net/http/pprof"
)func main() {// pprof 的初始化函数会被调用,但我们不使用其任何导出函数
}

3. 包的初始化顺序

每个包都可以包含一个 init 函数,用于包的初始化逻辑。在导入时,init 函数会在包的所有其他函数之前执行。如果一个包被多次导入,init 函数只会执行一次。


  1. 在 Go 语言中,每个包都可以包含一个名为 init 的函数,用于执行包的初始化逻辑。这个 init 函数在包被导入时会自动执行,而不需要手动调用。它的作用是在包被使用之前执行一些必要的初始化工作。

  2. 当导入一个包时,其中的 init 函数会在包的所有其他函数之前被执行。这意味着在使用包中的其他函数之前,包的初始化工作会首先完成。

  3. 如果同一个包被多次导入,其中的 init 函数只会执行一次。这是因为 init 函数在整个程序生命周期内只会被执行一次,即使导入它的包被多次引用也不会重复执行。这确保了包的初始化逻辑只会执行一次,避免了重复的初始化工作和可能的副作用。


总的来说,init 函数是用于包的初始化的特殊函数,它在导入时自动执行,负责包的初始化工作,并且只会执行一次,即使包被多次导入也不会重复执行。

下面是一个简单的示例来演示这个行为:
假设有一个名为 example 的包,其中包含一个 init 函数:

// example.go
package exampleimport "fmt"func init() {fmt.Println("Initializing example package")
}

然后,我们在另一个文件中多次导入 example 包:

// main.go
package mainimport ("example""example"
)func main() {fmt.Println("Main function")
}

当执行 main.go 文件时,我们可以看到 example 包的 init 函数只会被执行一次,即使该包被多次导入。

输出结果:

Initializing example package
Main function

4. 循环导入

Go 不允许包之间存在循环导入依赖。例如,包 A 导入包 B,包 B 又导入包 A,这会导致编译错误。解决循环导入问题的方法包括重构代码、使用接口或将共有逻辑提取到第三个包中。

循环导入问题通常是由于包之间的相互依赖关系不正确引起的。下面是一个简单的示例来模拟循环导入问题以及解决方法:
假设有两个包 A 和 B,它们互相导入并且存在循环依赖:

// a.go
package aimport "b"func AFunc() {b.BFunc()
}
// b.go
package bimport "a"func BFunc() {a.AFunc()
}

在这种情况下,当尝试编译时会出现循环导入错误。
解决循环导入问题的方法之一是重构代码,将共享的逻辑提取到第三个包中。例如,我们可以创建一个新的包 common,将两个包的共享逻辑移动到其中:

// common.go
package commonfunc CommonFunc() {// 共享逻辑
}

然后,包 A 和包 B 分别导入 common 包并使用其中的逻辑:

// a.go
package aimport "common"func AFunc() {common.CommonFunc()
}
// b.go
package bimport "common"func BFunc() {common.CommonFunc()
}

通过这种方式,我们消除了循环导入问题,并且可以在不同的包之间共享逻辑。

5. 包的可见性

在 Go 中,包内标识符的首字母大小写决定了其可见性。首字母大写的标识符是导出的,可以被其他包访问;首字母小写的标识符是包内私有的,不能被其他包访问。

package mypackage// 导出函数
func PublicFunc() {// ...
}// 私有函数
func privateFunc() {// ...
}

总结
Go 的包和导入机制提供了强大的模块化支持,帮助开发者组织代码和管理依赖性。通过合理使用包,可以提高代码的可维护性和可重用性。理解包的定义、导入方法、初始化顺序和可见性规则,是掌握 Go 语言的重要一步。


下一篇:二、Go语言入门(变量声明和函数调用)


在这里插入图片描述

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

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

相关文章

mysql授权用户

mysql授权用户只能看到某张表单表 要实现MySQL中的用户只能看到某张表,可以通过创建一个新的数据库用户,并且只授予该用户对特定表的权限。以下是实现这一功能的步骤和示例代码: 创建新用户并设置密码。 授予该用户对特定数据库的权限。 授…

国内最受欢迎的7大API供应平台对比和介绍||电商API数据采集接口简要说明

本文将介绍7款API供应平台:聚合数据、百度APIStore、Apix、数说聚合、通联数据、HaoService、datasift 。排名不分先后! 免费实用的API接口 第一部分 1、聚合数据(API数据接口_开发者数据定制) 2、百度API Store(API集市_APIStore…

数据库系统原理实验报告6 | 视图

整理自博主本科《数据库系统原理》专业课自己完成的实验报告,以便各位学习数据库系统概论的小伙伴们参考、学习。 专业课本: ​ ———— 本次实验使用到的图形化工具:Heidisql ​ 目录 一、实验目的 二、实验内容 1.根据EDUC数…

妙解设计模式之适配器模式

适配器模式的概念 适配器模式是一种结构设计模式,它允许将接口不兼容的类通过一个适配器类进行适配,使得这些类可以一起工作。适配器模式通常用于以下情况: 当一个接口的实现类已经存在,但是另一个接口需要的是不兼容的时候。当…

揭秘C++ String容器:字符串操作的艺术

目录 ​编辑 引言 一、初识std::string:构造与初始化 二、字符串的操纵艺术:拼接、查找与替换 三、访问与遍历:字符的细腻触感 四、大小与容量:动态调整的智慧 五、进阶功能:探索更多可能 结语 引言 在C标准库…

ssms执行建表后如何自动刷新所有SQL SERVER表

在 SQL Server Management Studio (SSMS) 中,当你通过 T-SQL 脚本创建表后,通常需要手动刷新对象资源管理器以查看新表。SSMS 并没有提供自动刷新的选项,但你可以使用以下几种方法来解决这个问题: 手动刷新:在对象资源…

网络工程师基础知识:

网络工程师基础知识: 1.最基本的7层协议: 来源: 通过网络网线和报文的这些机制让全世界的数据通过二进制流来进行沟通 从下而上: 物理层 数据链路层 网络层 传输层 表示层 会话层 应用层 基本的一个数据报文: 数据链…

Java 8

这次我学习了第八次Java课程 这次课在假期,包含了两天的一大波内容 对于编写项目过程中有许多的 辅助类 System System.out.println() 打印 Scanner Scanner sc new Scanner(System.in) 赋值 Random 随机数 Math 数学运算 日期 要想使用日期方法就要引入包Date 1…

人工智能为犯罪地下世界带来了巨大的生产力提升

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Java 18 新特性详解

Java 18 新特性详解 Java 18 作为 Oracle 推出的又一重要版本,继续秉持着 Java 平台“创新但不破坏”的原则,带来了多项旨在提升开发效率、性能和安全性的新特性。本篇文章将深入解析 Java 18 引入的主要特性,并探讨它们如何影响开发者的工作…

详解 Scala 的集合类型

一、集合简介 1. 类型 序列 Seq:类似于 Java 中的 List 接口集 Set:类似于 Java 中的 Set 接口映射 Map:类似于 Java 中的 Map 接口所有的集合都扩展自 Iterable 特质 2. 不可变集合 位于 scala.collection.immutable 包,指该集…

Runtime,你学会了吗?

作为Java开发者,我们经常听到关于Runtime类的提及,但很少有人深入了解它的作用和用法。 Runtime类是Java标准库中的一个关键类,提供了与运行时环境交互的方法。 本文将深入探讨Runtime类的背景、用途、常用方法以及最佳实践,帮助程序员们更好地利用这一重要工具。 1. 背…

ISSCC论文详解 2023 16.1 MulTCIM 存内计算在多模态领域的应用前沿论文

多模态模型,是指具备理解来自不同模态(如视觉、自然语言、语音等)的混合信号能力的神经网络模型,是当今人工智能模型发展的重要方向之一。本文将要介绍的文献题目为《16.1 MulTCIM: A 28nm 2.24μJ/Token Attention-Token-Bit Hyb…

一些常见的程序设计问题

秒杀 redis缓存库存 1.判断库存名额是否充足,2.进行扣减 为了防止超卖,必须保证这两部的原子性 库存扣减后发送mq消息,去异步执行创建订单流程,创建订单失败会造成少卖。可加重试机制,对多次重试依旧失败的&#xff…

刷题记录第九十九天-与排序相关的题-第K大的数和逆序对的数量

求第K大的数—利用快速排序的思想 class Solution { public:int partition(vector<int>& num, int l, int r){swap(num[l],num[lrand()%(r-l1)]);int x num[l];int il1, jr;while(i<j){while(i<r&&num[i]<x){i;}while(num[j]>x){j--;}if(i>…

SpringBoot自动化配置原理

Spring Boot 的自动化配置原理基于 EnableAutoConfiguration 注解及其相关机制。以下是其工作原理的详细说明&#xff1a; Spring Boot 自动化配置原理 主要概念和机制&#xff1a; EnableAutoConfiguration 注解&#xff1a; 这个注解告诉 Spring Boot 启动时去自动配置 Spr…

【java程序设计期末复习】chapter7 内部类和异常类

内部类和异常类 内部类 ava支持在一个类中声明另一个类&#xff0c;这样的类称作内部类&#xff0c;而包含内部类的类成为内部类的外嵌类。 注意 &#xff08;1&#xff09;内部类的类体中不可以声明类变量和类方法。 &#xff08;2&#xff09;外嵌类的类体中可以用内部类…

[论文阅读笔记31]Mamba (Selective Structured State Space Model) 及其应用

最近想学一下Mamba模型&#xff0c;奈何看了很多视频还是感觉一知半解&#xff0c;因此做一篇笔记&#xff0c;顺便介绍一下Mamba结构作为CV backbone和时间序列预测领域的应用。 论文1. Mamba: Linear-Time Sequence Modeling with Selective State Spaces 0. Abstract 现有…

VLAN高级特性

1.VLAN聚合 &#xff08;1&#xff09;VLAN聚合产生的技术背景 &#xff08;2&#xff09;VLAN聚合概述 &#xff08;3&#xff09;VLAN聚合的原理 多个Sub-VLAN共享一个网关地址&#xff0c;节约了子网网络地址、子网定向广播地址、子网缺省网关地址&#xff0c;且各Sub-VLAN…

微信小程序--微信开发者工具使用小技巧(3)

一、微信开发者工具使用小技巧 1、快速创建小程序页面 在app.json中的pages配置项&#xff0c;把需要创建的页面填写上去 2、快捷键使用 进入方式 1&#xff1a; 文件–>首选项–> keyboard shortcuts 进入快捷键查看与设置 进入方式 2&#xff1a; 设置–>快捷键…