【Golang - 90天从新手到大师】Day11 - 包的管理

 系列文章合集

Golang - 90天从新手到大师

Go语言中包的使用

Go语言使用包(package)这种语法元素来组织源码,所有语法可见性均定义在package这个级别,与Java 、python等语言相比,这算不上什么创新,但与C传统的include相比,则是显得“先进”了许多。

myblog
├── conf
│   └── app.conf
├── controllers
│   ├── aboutme_controller.go
│   ├── add_article_controller.go
│   ├── album_controller.go
│   ├── base_controller.go
│   ├── default.go
│   ├── delete_article_controller.go
│   ├── exit_controller.go
│   ├── home_controller.go
│   ├── login_controller.go
│   ├── register_controller.go
│   ├── show_article_controller.go
│   ├── tags_controller.go
│   ├── update_article_controller.go
│   └── upload_controller.go
├── main.go
├── models
│   ├── album_model.go
│   ├── article_model.go
│   ├── home_model.go
│   ├── tags_model.go
│   └── user_model.go
├── myblogweb
├── routers
│   └── router.go
├── static
│   ├── css
│   │   ├── blogsheet.css
│   │   └── lib
│   │       ├── highlight.css
│   │       └── login.css
│   ├── img
│   ├── js
│   │   ├── blog.js
│   │   ├── lib
│   │   │   ├── jquery-3.3.1.min.js
│   │   │   └── jquery.url.js
│   │   └── reload.min.js
│   └── upload
│       └── img
│           └── 2018
│               └── 12
│                   └── 11
│                       ├── 1544511378-bee2.png
├── tests
│   └── default_test.go
├── utils
│   ├── myUtils.go
│   └── mysqlUtils.go
└── views├── aboultme.html├── album.html├── block│   ├── home_block.html│   └── nav.html├── home.html├── index.tpl├── login.html├── register.html├── show_article.html├── tags.html└── write_article.html

Go 语言的源码复用建立在包(package)基础之上。包通过 package, import, GOPATH 操作完成。

1、 main包

Go 语言的入口 main() 函数所在的包(package)叫 main,main 包想要引用别的代码,需要import导入!

2、 package

src 目录是以代码包的形式组织并保存 Go 源码文件的。每个代码包都和 src 目录下的文件夹一一对应。每个子目录都是一个代码包。

代码包包名和文件目录名,不要求一致。比如文件目录叫 hello,但是代码包包名可以声明为 “main”,但是同一个目录下的源码文件第一行声明的所属包,必须一致!

同一个目录下的所有.go文件的第一行添加 包定义,以标记该文件归属的包,演示语法:

package 包名

包需要满足:

  • 一个目录下的同级文件归属一个包。也就是说,在同一个包下面的所有文件的package名,都是一样的。

  • 在同一个包下面的文件package名都建议设为是该目录名,但也可以不是。也就是说,包名可以与其目录不同名。

  • 包名为 main 的包为应用程序的入口包,其他包不能使用。

在同一个包下面的文件属于同一个工程文件,不用import包,可以直接使用

包可以嵌套定义,对应的就是嵌套目录,但包名应该与所在的目录一致,例如:

// 文件:qf/ruby/tool.go中
package ruby
// 可以被导出的函数
func FuncPublic() {
}
// 不可以被导出的函数
func funcPrivate() {
}

包中,通过标识符首字母是否大写,来确定是否可以被导出。首字母大写才可以被导出,视为 public 公共的资源。

3、 import

要引用其他包,可以使用 import 关键字,可以单个导入或者批量导入,语法演示:

A:通常导入

// 单个导入
import "package"
// 批量导入
import ("package1""package2")

B:点操作 我们有时候会看到如下的方式导入包

import(. "fmt"
) 

这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调

用的fmt.Println("hello world")可以省略的写成Println("hello world")

C:起别名

别名操作顾名思义我们可以把包命名成另一个我们用起来容易记忆的名字。导入时,可以为包定义别名,语法演示:

import (p1 "package1"p2 "package2")
// 使用时:别名操作,调用包函数时前缀变成了我们的前缀
p1.Method()

D:_操作 如果仅仅需要导入包时执行初始化操作,并不需要使用包内的其他函数,常量等资源。则可以在导入包时,匿名导入。

这个操作经常是让很多人费解的一个操作符,请看下面这个import:

import ("database/sql"_ "github.com/ziutek/mymysql/godrv") 

_操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。也就是说,使用下划线作为包的别名,会仅仅执行init()。

导入的包的路径名,可以是相对路径也可以是绝对路径,推荐使用绝对路径(起始于工程根目录)。

4、GOPATH环境变量

import导入时,会从GO的安装目录(也就是GOROOT环境变量设置的目录)和GOPATH环境变量设置的目录中,检索 src/package 来导入包。如果不存在,则导入失败。 GOROOT,就是GO内置的包所在的位置。 GOPATH,就是我们自己定义的包的位置。

通常我们在开发Go项目时,调试或者编译构建时,需要设置GOPATH指向我们的项目目录,目录中的src目录中的包就可以被导入了。

5、init() 包初始化

下面我们详细的来介绍一下这两个函数:init()、main() 是 go 语言中的保留函数。我们可以在源码中,定义 init() 函数。此函数会在包被导入时执行,例如如果是在 main 中导入包,包中存在 init(),那么 init() 中的代码会在 main() 函数执行前执行,用于初始化包所需要的特定资料。例如: 包源码:

src/userPackage/tool.go
package userPackage
import "fmt"
func init() {fmt.Println("tool init")
}

主函数源码:

src/main.go
package main
import ("userPackage")
func main() {fmt.Println("main run")// 使用userPackageuserPackage.SomeFunc()
}

执行时,会先输出 "tool init",再输出 "main run"。

下面我们详细的来介绍一下init()、main() 这两个函数。在 go 语言中的区别如下: 相同点:

两个函数在定义时不能有任何的参数和返回值。 该函数只能由 go 程序自动调用,不可以被引用。

不同点:

init 可以应用于任意包中,且可以重复定义多个。 main 函数只能用于 main 包中,且只能定义一个。

两个函数的执行顺序:

在 main 包中的 go 文件默认总是会被执行。

对同一个 go 文件的 init( ) 调用顺序是从上到下的。

对同一个 package 中的不同文件,将文件名按字符串进行“从小到大”排序,之后顺序调用各文件中的init()函数。

对于不同的 package,如果不相互依赖的话,按照 main 包中 import 的顺序调用其包中的 init() 函数。

如果 package 存在依赖,调用顺序为最后被依赖的最先被初始化,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main,一次执行对应的 init 方法。main 包总是被最后一个初始化,因为它总是依赖别的包

图片

图片引自网络

避免出现循环 import,例如:A –> B –> C –> A。

一个包被其它多个包 import,但只能被初始化一次

6、管理外部包

go允许import不同代码库的代码。对于import要导入的外部的包,可以使用 go get 命令取下来放到GOPATH对应的目录中去。

举个例子,比如说我们想通过go语言连接mysql数据库,那么需要先下载mysql的数据包,打开终端并输入以下命令:

localhost:~ ruby$ go get github.com/go-sql-driver/mysql

安装之后,就可以在gopath目录的src下,看到对应的文件包目录:

图片

也就是说,对于go语言来讲,其实并不关心你的代码是内部还是外部的,总之都在GOPATH里,任何import包的路径都是从GOPATH开始的;唯一的区别,就是内部依赖的包是开发者自己写的,外部依赖的包是go get下来的。

扩展

我们可以通过go install 来编译包文件。

我们知道一个非main包在编译后会生成一个.a文件(在临时目录下生成,除非使用go install安装到$GOROOT$GOPATH下,否则你看不到.a),用于后续可执行程序链接使用。

比如Go标准库中的包对应的源码部分路径在:$GOROOT/src,而标准库中包编译后的.a文件路径在$GOROOT/pkg/darwin_amd64下。


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

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

相关文章

大型语言模型在AMD GPU上的推理优化

Large language model inference optimizations on AMD GPUs — ROCm Blogs 大型语言模型(LLMs)已经改变了自然语言处理和理解,促进了在多个领域中的众多人工智能应用。LLMs在包括AI助手、聊天机器人、编程、游戏、学习、搜索和推荐系统在内的…

Linux管道与重定向

管道 是进程通信的方法之一,在Linux中用命令1|命令2的形式表示,将前一个命令的结果作为后续命令的参数进行输入,也有tee管道,可以进行多次筛选,即多次使用|过滤命令。 重定向 文件描述符FD Linux中输入输出分为三种…

windows常见问题

文章目录 Windows下常见问题1. 修改hosts文件2. win10系统卸载edge浏览器 Windows下常见问题 1. 修改hosts文件 hosts文件位置:C:\Windows\System32\drivers\etc\hosts 随便打开一个文件夹,然后在地址栏中输入上面的路径,然后选择使用txt编…

【AI应用探讨】— 盘古大模型应用场景

目录 一、自然语言处理领域 智能客服 机器翻译 语音识别 二、计算机视觉领域 图像分类 目标检测 图像分割 图像生成 三、科学计算领域 气象预测 矿山安全 铁路检测 药物研发 一、自然语言处理领域 智能客服 利用盘古NLP大模型的语言理解和生成能力,提…

基于AT32_Work_Bench配置AT32工程

基于AT32_Work_Bench配置AT32工程 ✨AT32_Work_Bench工具是用来给AT32 MCU快速构建外设初始化工程软件,类似STM32的STM32CubeMX工具软件。 📍AT32 TOOL系列工具下载地址:https://www.arterytek.com/cn/support/index.jsp?index4&#x1f3f7…

INFINI Labs 助力开源与教育:免费许可证计划全面升级

在数字化浪潮席卷全球的今天,INFINI Labs 深刻认识到开源项目和教育机构在技术创新与人才培养中的核心作用。因此,我们郑重推出全新升级的免费许可证计划,旨在全球范围内为开源社区和教育界提供有力支持,共同推动软件生态的繁荣与…

空压机节能元宇宙:未来工业能源效率的革命

随着全球工业化进程的加速,能源消耗和环境保护已成为全球关注的焦点。在众多工业设备中,空压机作为一种重要的动力设备,其能耗问题尤为突出。为了实现节能减排和可持续发展,探索空压机的节能潜力和创新应用显得尤为重要。在这一背…

什么是数据库?从零开始了解数据库基础概念

什么是数据库?从零开始了解数据库基础概念 相信大家在日常生活中都听到过大数据,数据这个东西越来越火,比如交通大数据、旅游大数据等,,,数据成为了企业决策和业务运作的关键元素。而管理这些庞大而复杂的…

14、顺时针打印矩阵

题目: 顺时针打印矩阵 描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字, 例如, 如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字:1,2,3,4,8,1…

nginx出现504 Gateway Time-out错误的原因分析及解决

nginx出现504 Gateway Time-out错误的原因分析及解决 1、查看公网带宽是否被打满 2、查看网络是否有波动(可以在nginx上ping后端服务,看是否有丢包情况) 3、查看服务器资源使用情况(cpu、内存、磁盘、网络等) 4、查看nginx日志,具体到哪个服务的哪个…

kali中安装docker

文章目录 前期准备安装步骤后续设置 前期准备 更新系统包列表: 打开终端,首先更新你的系统包列表,确保安装的是最新版本的软件包。 sudo apt update安装依赖: 安装docker.io所需的依赖包。这一步确保了系统具备安装Docker的基本条…

SQL - CTE

CTE,全称为 Common Table Expression(公用表表达式),是一种 SQL 表达式,用于命名一个临时结果集,这个结果集仅在执行单个查询(包括 SELECT、INSERT、UPDATE 或 DELETE 语句)期间可用…

如何利用AI大模型设计电机本体?

一、背景 AI在电机本体设计中的应用正逐渐成为提升设计效率、优化性能和降低成本的重要手段。通过深度学习、机器学习、计算机辅助设计(CAD)和仿真技术的结合,AI能够帮助工程师更快速准确地完成电机的设计与优化工作。以下是AI在电机本体设计…

02_02_SpringMVC基于注解的应用

一、请求处理 1、常用注解 RequestMapping 作用:用来匹配客户端发送的请求(用来处理URL映射,将请求映射到处理方法中),可以在类或者方法上使用。 用在类上,可以将请求模块化,避免请求方法中的…

网络编程(二)TCP编程 TCP粘包问题

文章目录 一、TCP网络编程(一)流程(二)相关函数1. socket2. bind3. listen4. accept5. connect 二、收发函数(一)send函数(二)recv函数 三、TCP粘包问题(一)将…

详细分析Matplotlib 绘制三维曲线图的细节(附Demo)

目录 前言1. 基本知识2. Demo 前言 对于Matplotlib的基本知识推荐阅读:python之Matplotlib详细分析(附代码) 1. 基本知识 Matplotlib 是 Python 中常用的绘图库,可以用于生成各种类型的图表,包括三维曲线图 在三维…

Shiro721 反序列化漏洞(CVE-2019-12422)

目录 Shiro550和Shiro721的区别 判断是否存在漏洞 漏洞环境搭建 漏洞利用 利用Shiro检测工具 利用Shiro综综合利用工具 这一篇还是参考别的师傅的好文章学习Shiro的反序列化漏洞 上一篇也是Shiro的反序列化漏洞,不同的是一个是550一个是721,那么这…

【node】启动本地打包文件的方式

前言 … 目标 1 初始化node文件 2 将打包文件通过node发布到本地 3 系列文件 【node】创建本地接口 一 node方式 1 在新建一个空的文件夹node 进入空文件夹在,文件夹的地址栏输入cmd回车,会自动跳转到命令行工具里 2 配置初始化文件 在命令行输入命令npm init,生成pac…

2024年选择计算机相关专业仍然是一个明智的决定。这个领域不仅具有强大的就业前景和高薪水,还提供了许多创新和发展的机会。

方向一:行业竞争现状 当前计算机行业的竞争现状和市场饱和度 1. 行业饱和度 计算机行业的某些传统领域,如软件开发中的常规应用开发和基础IT服务,已经趋于饱和。市场上存在大量的公司和个人开发者,竞争非常激烈。然而,…

驾校OBD接入CAN总线数据大众朗逸仪表网关位置

在汽车的复杂电路网络中,仪表网关扮演着信息枢纽的角色。对于驾校使用大众朗逸车主而言,了解仪表网关的位置不仅有助于日常维护,更是故障诊断和车辆升级的关键所在。 大众朗逸作为一款深受消费者喜爱的车型,凭借其稳定的性能和经…