当前位置: 首页 > news >正文

golang包的管理

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.gopackage userPackage
import "fmt"
func init() {fmt.Println("tool init")
}

主函数源码:

src/main.gopackage 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

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

扩展

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

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

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

相关文章:

golang包的管理

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

Windows10安装Anaconda与Pytorch的记录

这是一篇关于安装Anaconda和Pytorch的记录与复盘,写的原因是我电脑恢复系统之后东西全没了,再装Pytorch的时候一脸懵逼忘了怎么弄了,写篇记录以备我下一次安装。 1、Anaconda的安装 1.1、Anaconda安装包下载 下载链接: Free Download | An…...

图解Kafka高性能之谜(五)

高性能的多分区、冗余副本集群架构 高性能网络模型NIO 简单架构设计: 详细架构设计: 高性能的磁盘写技术 高性能的消息查找设计 索引文件定位使用跳表的设计 偏移量定位消息时使用稀疏索引: 高响应的磁盘拷贝技术 kafka采用sendFile()的…...

opencv在linux上调用usb摄像头进行拍照

功能 1.按照指定的文件名创建文件夹,创建之前判断该文件夹是否存在 2.调用摄像头按可调整窗口大小的方式显示 3.按esc退出摄像头画面 4.按p保存当前摄像头的画面,并按当前时间为照片的名字进行保存打开终端查看是否有摄像头 ls /dev/video*一般video1就…...

软考之知识产品+例题

知识产权 保护期限 公民作品 没有限制 署名权、修改权、保护作品完整权 作者终生及其死亡后的第 50 年的 12月31日 发表权、使用权、获得报酬权 单位作品 首次发表后的第 50 年的 12月31 日,若未发表则不受保护 发表权、使用权、获得报酬权 公民软件作品 没…...

玩了一下 Jenkins,最新版本 + JDK11

背景 今年五月的时候玩了一下 Jenkins,最新版本 2.414.3 ,JDK 11 。本机有两个 JDK,只放到 Tomcat 里面了,看到了一个启动页面,后面有其他事情就忘记了。最近又想起来,觉得还是应该玩一下这么有技术含量的…...

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试,开源项目

自定义的卷积神经网络模型CNN,对图片进行分类并使用图片进行测试模型-适合入门,从模型到训练再到测试:开源项目 开源项目完整代码及基础教程: https://mbd.pub/o/bread/ZZWclp5x CNN模型: 1.导入必要的库和模块&…...

C# 使用.NET的SocketAsyncEventArgs实现高效能多并发TCPSocket通信

简介: SocketAsyncEventArgs是一个套接字操作得类,主要作用是实现socket消息的异步接收和发送,跟Socket的BeginSend和BeginReceive方法异步处理没有多大区别,它的优势在于完成端口的实现来处理大数据的并发情况。 BufferManager类…...

设计模式——观察者模式(Observer Pattern)+ Spring相关源码

文章目录 一、观察者模式定义二、例子2.1 菜鸟教程例子2.1.1 定义观察者2.1.2 定义被观察对象2.1.3 使用 2.2 JDK源码 —— Observable2.2.1 观察者接口Observer2.2.1 被观察者对象Observable 2.3 Spring源码 —— AbstractApplicationContext2.3.1 观察者2.3.2 被观察者 2.3 G…...

openpnp - code review - 开机对话框历史记录和贡献者名单

文章目录 openpnp - code review - 开机对话框历史记录和贡献者名单概述笔记D:\my_openpnp\openpnp_dev_2022_0801\src\main\java\org\openpnp\gui\AboutDialog.javaEND openpnp - code review - 开机对话框历史记录和贡献者名单 概述 偶然发现, 自己打包后的openpnp, 开机后…...

JavaSE22——HashMap

集合框架_HashMap 一、概述 HashMap 是用于存储 Key-Value 键值对的集合。 (1)HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,所以具有很快的访问速度,但遍历顺序不确定。 (2&…...

「图像 merge」无中生有制造数据

在进行一个新项目的时候,往往缺少一些真实数据,导致没办法进行模型训练,这时候就需要算法工程师自行制作一些数据了,比如这篇文章分享的 bag 目标检测,在检测区域没有真实的 bag数据 此时,就可以采用图像拼…...

RK3588之ArmSoM-W3 + MPP实现多路硬解码拉流

简介 学习完MPP的解码Demo之后,想必大家都想通过一个项目来进行RK3588-MPP的解码实战。本篇文章就基于ArmSoM-W3开发板,开发一个多路硬解码项目,实现四路MPP硬解码拉流显示实现的效果如下: RK3588四路MPP硬解码拉流 环境介绍 硬件…...

【Rust日报】2023-10-29 隆重推出 Rerun 0.10!

Lapce代码编辑器发布v0.3.0 Lapce代码编辑器新发布v0.3.0! https://lapce.dev/ 距离我们上次发布已经过去很长一段时间了。我们正忙着在自己的 UI 工具包Floem中重写 Lapce ,这将使我们以后对 UI 部分代码的开发变得更容易、更快。 另一件值得注意的事情…...

AI智能识别如何助力PDF,轻松实现文档处理?

AI智能识别如何助力PDF,轻松实现文档处理? 随着科技的不断发展,人工智能(AI)在各个领域都发挥着重要的作用。其中,文档智能( Document AI )在金融、医疗、教育、保险、能源、物流等…...

【SA8295P 源码分析】114 - 将Android GVM userdata文件系统从 EXT4 修改为 F2FS

【SA8295P 源码分析】114 - 将Android GVM userdata文件系统从 EXT4 修改为 F2FS 一、代码修改方法1. BoardConfig.mk2. 修改 fstab二、开机进入 adb 验证2.1 验证 userdata 修改 f2fs 文件系统格式成功2.2 测试 f2fs 文件系统性能:androbench.apk系列文章汇总见:《【SA8295P…...

LeetCode 387 字符串中的第一个唯一字符 简单

题目 - 点击直达 1. 387 字符串中的第一个唯一字符1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. 387 字符串中的第一个唯一字符 1. 题目详情 给定一个字符串 s ,找到 它的第一个不重复的字符,并返…...

线程池--简单版本和复杂版本

目录 一、引言 二、线程池头文件介绍 三、简单版本线程池 1.创建线程池 2.添加任务到线程池 3.子线程执行回调函数 4.摧毁线程池 5.简单版线程池流程分析 四、复杂版本线程池 1.结构体介绍 2.主线程 3.子线程 4.管理线程 一、引言 多线程版服务器一个客户端就需要…...

docker进阶

文章目录 docker 进阶Part1 常用命令总结docker version 查看docker客户端和服务端信息docker info 查看更加详细信息docker images 列出所有镜像基本用法常用选项 docker search 搜索镜像基本用法示例用法 docker pull 拉取镜像基本用法示例用法 docker rmi 删除镜像基本用法示…...

Unity HoloLens 2 应用程序发布

设置3D 启动器画面,glb格式的模型 VS中可以直接生成所有大小的图标...

VSCode - VSCode 放大与缩小代码

VSCode 放大与缩小代码 1、放大 点击顶部菜单栏【查看】 -> 点击外观 -> 点击【放大】 或者,使用快捷键:Ctrl # 操作方式先按住 Ctrl 键,再按 键2、缩小 点击顶部菜单栏【查看】 -> 点击外观 -> 点击【缩小】 或者&#x…...

多系统一键打包docker compose下所有镜像并且使用

本方法适合在已经pull好docker镜像正常使用的机器 将环境迁移到无网络 或者网络不好的机器使用 linux 用法 cd 到 docker-compose.yml 所在目录 ./save_compose_images.sh #!/bin/bash # 拉取镜像并保存为 .tar 文件 docker save $(docker-compose images | awk {print…...

【SSM】SpringBoot笔记2:整合Junit、MyBatis

前言: 文章是系列学习笔记第9篇。基于黑马程序员课程完成,是笔者的学习笔记与心得总结,供自己和他人参考。笔记大部分是对黑马视频的归纳,少部分自己的理解,微量ai解释的内容(ai部分会标出)。 …...

探秘鸿蒙 HarmonyOS NEXT:实战用 CodeGenie 构建鸿蒙应用页面

在开发鸿蒙应用时,你是否也曾为一个页面的布局反复调整?是否还在为查 API、写模板代码而浪费大量时间?今天带大家实战体验一下鸿蒙官方的 AI 编程助手——CodeGenie(代码精灵) ,如何从 0 到 1 快速构建一个…...

SQL Server全局搜索:在整个数据库中查找特定值的高效方法

SQL Server全局搜索:在整个数据库中查找特定值的高效方法 一、需求背景:为什么需要数据库全局搜索? 在数据库管理和开发过程中,我们经常会遇到这样的场景: 只记得某个数据值,但忘记了它所在的表或列需要…...

深入浅出Java ParallelStream:高效并行利器还是隐藏的陷阱?

在Java 8带来的众多革新中,Stream API彻底改变了我们对集合操作的方式。而其中最引人注目的特性之一便是parallelStream——它承诺只需简单调用一个方法,就能让数据处理任务自动并行化,充分利用多核CPU的优势。但在美好承诺的背后&#xff0c…...

第3章——SSM整合

一、整合持久层框架MyBatis 1.准备数据库表及数据 创建数据库:springboot 使用IDEA工具自带的mysql插件来完成表的创建和数据的准备: 创建表 表创建成功后,为表准备数据,如下: 2.创建SpringBoot项目 使用脚手架创建…...

亚矩阵云手机实测体验:稳定流畅背后的技术逻辑​

最近在测试一款云手机服务时,发现亚矩阵的表现出乎意料地稳定。作为一个经常需要多设备协作的开发者,我对云手机的性能、延迟和稳定性要求比较高。经过一段时间的体验,分享一下真实感受,避免大家踩坑。 ​​1. 云手机能解决什么问…...

使用 Python 构建并调用 ComfyUI 图像生成 API:完整实战指南

快速打造你自己的本地 AI 图像生成服务,支持 Web 前端一键调用! 📌 前言 在 AIGC 快速发展的今天,ComfyUI 作为一款模块化、节点式的图像生成界面,备受开发者青睐。但默认情况下,ComfyUI 主要通过界面交互…...

CVAT标注服务

CVAT 是一个交互式的视频和图像标注工具,适用于计算机视觉,是一个典型的现代Web应用架构,可以实现大部分情况的标注工作,可以通过serveless CVAT-github cvat文档 下面将就其配置介绍一下几个服务: 1. 核心服务 (C…...