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

news2025/3/17 7:40:04

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 main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

1.4 非 main 包

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

package mathutils

func Add(a int, b int) int {
    return a + b
}

2. 导入(Import)

2.1 导入标准库

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

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, World!")
}

2.2 导入第三方包

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

go get github.com/gin-gonic/gin

然后在代码中导入:

package main

import (
    "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 main

import (
    "fmt"
    "project/mathutils"
)

func main() {
    result := mathutils.Add(1, 2)
    fmt.Println(result)
}

2.4 导入别名

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

package main

import (
    f "fmt"
)

func main() {
    f.Println("Hello, World!")
}

2.5 导入并调用初始化函数

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

package main

import (
    _ "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 example

import "fmt"

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


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

// main.go
package main

import (
    "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 a

import "b"

func AFunc() {
    b.BFunc()
}

// b.go
package b

import "a"

func BFunc() {
    a.AFunc()
}

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

// common.go
package common

func CommonFunc() {
    // 共享逻辑
}

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

// a.go
package a

import "common"

func AFunc() {
    common.CommonFunc()
}

// b.go
package b

import "common"

func BFunc() {
    common.CommonFunc()
}

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

5. 包的可见性

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

package mypackage

// 导出函数
func PublicFunc() {
    // ...
}

// 私有函数
func privateFunc() {
    // ...
}

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


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


在这里插入图片描述

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

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

相关文章

第四课 communcation服务-can配置第二弹

Davinci配置目标: 介绍DBC基本属性,并且配置出一个DBC。 将DBC导入到vector的davinci工具,生成我们想要的代码。 Davinci配置步骤: 1. 编辑DBC文件 DBC文件是一种非常重要的工具,所谓DBC就是Database CAN,CAN网络的数据库文件,定义了CAN网络的节点、消息、信号的所有…

查看远程桌面连接登录不上服务器,远程桌面连接登录不上服务器是什么情况?怎么解决?

在信息技术领域,远程桌面连接(RDP)是一种重要的远程管理工具,它允许管理员或用户从远程位置访问和控制服务器或计算机。然而,在实际操作中,远程桌面连接不上服务器的情况时有发生,这通常是由多种…

Redis 完整

Redis 什么是 redis ? 是一种基于键值对的 NoSql 型数据库。与 hashMap 不同的是,Redis 中的 value 支持 string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset…

Kafka(十三)监控与告警

目录 Kafka监控与告警1 解决方案1.2 基础知识JMX监控指标代理查看KafkaJMX远程端口 1.3 真实案例Kafka Exporter:PromethusPromethus Alert ManagerGrafana 1.3 实际操作部署监控和告警系统1.2.1 部署Kafka Exporter1.2.2 部署Prometheus1.2.3 部署AlertManger1.2.4 添加告警规…

3D透视图转的时候模型闪动怎么解决?---模大狮模型网

在3D建模与渲染的世界中,透视图是我们观察和操作模型的重要窗口。然而,有时候在旋转透视图时,模型会出现闪动的现象,这不仅影响了我们的工作效率,还可能对最终的渲染效果产生负面影响。本文将探讨这一问题的成因&#…

【Text2SQL 经典模型】HydraNet

论文:Hybrid Ranking Network for Text-to-SQL ⭐⭐⭐ arXiv:2008.04759 HydraNet 也是利用 PLM 来生成 question 和 table schema 的 representation 并用于生成 SQL,并在 SQLova 和 X-SQL 做了改进,提升了在 WikiSQL 上的表现。 一、Intro…

WGCAT工单系统如何配置通知

WGCAT工单系统可以配置邮件通知 只要配置了邮件通知,那么一旦我们账号有新的工单需要处理,就会接受到邮件通知 除了邮件之外,还可以配置其他方式的通知,比如微信钉钉短信等方式,参考如下 https://www.wgstart.com/wgc…

Docker常用软件安装

文章目录 1.安装Tomcat1.docker hub查找镜像并复制拉取镜像命令2.拉取镜像到本地1.执行官网命令2.查看是否拉取成功 3.启动tomcat4.退出和重启1.由于是以交互方式启动的,所以不方便,直接ctrl c退出2.查看当前的容器3.使用docker start 命令启动容器&…

内外网文件传输安全可控的方式有哪些?这几款软件值得参考

在信息化时代,随着企业对网络安全和数据保护需求的日益增强,内外网隔离已成为一种常见的网络安全策略。内外网隔离旨在防止未经授权的访问和数据泄露,确保企业网络的安全稳定。然而,在实施内外网隔离的同时,如何实现文…

读书笔记-Java并发编程的艺术-第1章 并发编程的挑战

文章目录 1.1 上下文切换1.1.1 多线程一定快吗1.1.2 如何减少上下文切换 1.2 死锁1.3 资源限制的挑战 1.1 上下文切换 即时是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给多个线程的时间,因为时间…

H3CNE-6-ICMP数据包分析

ICMP:Internet Control Message Protocol ICMP用来传递差错、控制、查询等信息 Wireshark抓包 Wireshark下载国内镜像 ICMP数据包格式 Type:表示ICMP消息类型 Code:表示同一消息类型中的不同信息 ICMP消息类型和编码类型 ICMP应用 &…

idea中显示git的Local Changes

1. 第一打开idea中的Settings文件 2. 找到Version Contro中的commint 3. 取消勾选应用即可 4. 本地提交就会显示出来

Python高级进阶--dict字典

dict字典⭐⭐ 1. 字典简介 dictionary(字典) 是 除列表以外 Python 之中 最灵活 的数据类型,类型为dict 字典同样可以用来存储多个数据字典使用键值对存储数据 2. 字典的定义 字典用{}定义键值对之间使用,分隔键和值之间使用:分隔 d {中…

【Linux网络编程】传输层中的TCP和UDP(TCP篇)

【Linux网络编程】传输层中的TCP和UDP(TCP篇) 目录 【Linux网络编程】传输层中的TCP和UDP(TCP篇)TCP协议TCP协议段格式确认应答(ACK)机制(保证可靠性)超时重传机制连接管理机制理解T…

“等保测评与安全运维的协同:保障企业网络安宁

"等保测评与安全运维的协同:保障企业网络安宁"是一个涉及信息安全领域的重要话题。这里,我们可以从几个方面来探讨这个主题。 1. 等保测评(等级保护测评) 等保测评,即信息安全等级保护测评,是依…

社交媒体数据恢复:连信

在使用连信的过程中,如果我们误删了重要的照片或者文件,可以通过以下步骤进行数据恢复: 一、有备份恢复 若你在删除之前已经备份了相关照片或文件,那么恢复起来就相对容易一些。以下是具体的恢复步骤: 登录连信账号&…

vue data中的return

vue 的data return 是干啥的呢,vue中页面中绑定的变量都要放在data的return中,可以赋值,值可在script中改,修改引用就用this了 如果不使用return包裹的数据会在项目的全局中可见,会造成变量污染; 使用retu…

虚拟机启动Operating System not found找不到操作系统

错误信息 PEX-E51 No SHCP or proxyDHCP offers were received. PXE-M0F: Exiting Intel PXE ROM. Operating System not found解决方法1 到服务里面检查跟vmware相关的服务是否已经全部启动 如果服务怎么都无法启动,最简单的办法还是重装vmware 解决方法2 &#…

音视频开发5 补充 - Nginx搭建rtmp流媒体服务器,目的是让ffmpeg 可以直播推流

直播推流 ffmpeg -re -i out.mp4 -c copy flv rtmp://server/live/streamName -re, 表示按时间戳读取文件 参考: Nginx 搭建 rtmp 流媒体服务器 (Ubuntu 16.04) https://www.jianshu.com/p/16741e363a77 第一步 准备工作 安装nginx需要的依赖包 打开 ubutun 终端…

2024年5月26日 十二生肖 今日运势

小运播报:2024年5月26日,星期日,农历四月十九 (甲辰年己巳月庚寅日),法定节假日。 红榜生肖:马、猪、狗 需要注意:牛、蛇、猴 喜神方位:西北方 财神方位:…