【Golang】包

news2024/12/24 9:30:03

Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案

Go语言中为我们提供了很多内置包,如 fmt、os、io 等。

任何源代码文件必须属于某个包,同时源码文件的第一行有效代码必须是package pacakgeName 语句,通过该语句声明自己所在的包

1、包的基本概念

Go语言的包借助了目录树的组织形式,一般包的名称就是其源文件所在目录的名称

虽然Go语言没有强制要求包名必须和其所在的目录名同名,但还是建议包名和所在目录同名,这样结构更清晰

包可以定义在很深的目录中,包名的定义是不包括目录路径的,但是包在引用时一般使用全路径引用

包的习惯用法:

  • 包名一般是小写的,使用一个简短且有意义的名称
  • 包名一般要和所在的目录同名,也可以不同,包名中不能包含- 等特殊符号
  • 包名为 main 的包为应用程序的入口包,编译不包含 main 包的源码文件时不会得到可执行文件
  • 一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下

2、包的导入

要在代码中引用其他包的内容,需要使用 import 关键字导入使用的包。具体语法如下:

import "包的路径"

注意事项:

  • import 导入语句通常放在源码文件开头包声明语句的下面;
  • 导入的包名需要使用双引号包裹起来;

包的导入有两种写法,分别是单行导入和多行导入

//单行导入
import "包 1 的路径"
import "包 2 的路径"

//多行导入
import (
    "包 1 的路径"
    "包 2 的路径"
)

注意:

包的绝对路径就是GOROOT/src/GOPATH后面包的存放路径

3、包的引用格式

  • 标准引用格式

    package main
    import "fmt"
    func main() {
        fmt.Println("hello world")
    }
    

    此时可以用fmt.作为前缀来使用 fmt 包中的方法,这是常用的一种方式

  • 自定义别名引用格式

    package main
    import F "fmt"
    func main() {
        F.Println("hello world")
    }
    

    其中 F 就是 fmt 包的别名,使用时我们可以使用F.来代替标准引用格式的fmt.来作为前缀使用 fmt 包中的方法

  • 省略引用格式

    package main
    import . "fmt"
    func main() {
        //不需要加前缀 fmt.
        Println("hello world")
    }
    

    这种格式相当于把 fmt 包直接合并到当前程序中,在使用 fmt 包内的方法是可以不用加前缀fmt.,直接引用

  • 匿名引用格式

    package main
    import (
        _ "database/sql"
        "fmt"
    )
    func main() {
        fmt.Println("hello world")
    }
    

    在引用某个包时,如果只是希望执行包初始化的 init 函数,而不使用包内部的数据时,可以使用匿名引用格式

    匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中

    使用标准格式引用包,但是代码中却没有使用包,编译器会报错。如果包中有 init 初始化函数,则通过import _ "包的路径" 这种方式引用包,仅执行包的初始化函数,即使包没有 init 初始化函数,也不会引发编译器报错

  • 注意:

    • 一个包可以有多个 init 函数,包加载时会执行全部的 init 函数,但并不能保证执行顺序,所以不建议在一个包中放入多个 init 函数,将需要初始化的逻辑放到一个 init 函数里面。
    • 包不能出现环形引用的情况,比如包 a 引用了包 b,包 b 引用了包 c,如果包 c 又引用了包 a,则编译不能通过。
    • 包的重复引用是允许的,比如包 a 引用了包 b 和包 c,包 b 和包 c 都引用了包 d。这种场景相当于重复引用了 d,这种情况是允许的,并且 Go 编译器保证包 d 的 init 函数只会执行一次

4、go mod

go module 是Go语言从 1.11 版本之后官方推出的版本管理工具,并且从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具

Modules 官方定义为

Modules 是相关 Go 包的集合,是源代码交换和版本控制的单元

Go语言命令直接支持使用 Modules,包括记录和解析对其他模块的依赖性,Modules 替换旧的基于 GOPATH 的方法,来指定使用哪些源文件

使用go module之前需要设置环境变量:

  1. GO111MODULE=on
  2. GOPROXY=https://goproxy.io,directopen in new window
  3. GOPROXY=https://goproxy.cn,direct(国内的七牛云提供)

GO111MODULE 有三个值:off, on和auto(默认值)

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
    • 当前目录在GOPATH之外且该目录包含go.mod文件 开启
    • 当处于 GOPATH 内且没有 go.mod 文件存在时其行为会等同于 GO111MODULE=off
  • 如果不使用 Go Modules, go get 将会从模块代码的 master 分支拉取
  • 而若使用 Go Modules 则你可以利用 Git Tag 手动选择一个特定版本的模块代码

go mod 有以下命令

命令说明
downloadxdownload modules to local cache(下载依赖包)
editedit go.mod from tools or scripts(编辑go.mod)
graphprint module requirement graph (打印模块依赖图)
initinitialize new module in current directory(在当前目录初始化mod)
tidyadd missing and remove unused modules(拉取缺少的模块,移除不用的模块)
vendormake vendored copy of dependencies(将依赖复制到vendor下)
verifyverify dependencies have expected content (验证依赖是否正确)
whyexplain why packages or modules are needed(解释为什么需要依赖)
  • 常用的有 init tdiy edit

使用go get命令下载指定版本的依赖包:

执行go get 命令,在下载依赖包的同时还可以指定依赖包的版本。

  • 运行go get -u命令会将项目中的包升级到最新的次要版本或者修订版本;
  • 运行go get -u=patch命令会将项目中的包升级到最新的修订版本;
  • 运行go get [包名]@[版本号]命令会下载对应包的指定版本或者将对应包升级到指定的版本。

提示:go get [包名]@[版本号]命令中版本号可以是 x.y.z 的形式,例如 go get foo@v1.2.3,也可以是 git 上的分支或 tag,例如 go get foo@master,还可以是 git 提交时的哈希值,例如 go get foo@e3702bed2

  • 项目中使用

    在 GOPATH 目录下新建一个目录,并使用go mod init初始化生成 go.mod 文件

    go.mod 文件一旦创建后,它的内容将会被 go toolchain 全面掌控,go toolchain 会在各类命令执行时,比如go getgo buildgo mod等修改和维护 go.mod 文件

    go.mod 提供了 module、require、replace 和 exclude 四个命令:

    • module 语句指定包的名字(路径);
    • require 语句指定的依赖项模块;
    • replace 语句可以替换依赖项模块;
    • exclude 语句可以忽略依赖项模块。

    初始化生成的 go.mod 文件如下所示:

    在这里插入图片描述

添加依赖

新建一个 main.go 文件,写入以下代码

package main
import (
    "net/http"
    "github.com/labstack/echo"
)
func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, World!")
    })
    e.Logger.Fatal(e.Start(":1323"))
}

执行go mod tidy运行代码会发现 go mod 会自动查找依赖自动下载

在这里插入图片描述

go module 安装 package 的原则是先拉取最新的 release tag,若无 tag 则拉取最新的 commit

go 会自动生成一个 go.sum 文件来记录 dependency tree。

执行脚本go run main.go,就可以运行项目。

可以使用命令go list -m -u all来检查可以升级的 package,使用go get -u need-upgrade-package升级后会将新的依赖版本更新到 go.mod

比如:go get -u github.com/labstack/gommon

也可以使用go get -u升级所有依赖。

使用 replace 替换无法直接获取的 package:

由于某些已知的原因,并不是所有的 package 都能成功下载,比如:golang.org 下的包。

modules 可以通过在 go.mod 文件中使用 replace 指令替换成 github 上对应的库,比如:golang.org 下的包

replace (
    golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)

modules 可以通过在 go.mod 文件中使用 replace 指令替换成 github 上对应的库,比如:

replace (
    golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)

go install命令将项目打包安装为可执行文件,在安装在GOPATH的bin目录下,go install执行的项目 必须有main方法

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

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

相关文章

【2】c++设计模式——>UML表示类之间的继承关系

继承也叫作泛化(Generalization),用于描述父子类之间的关系,父类又称为基类或者超类,子类又称作派生类。在UML中,继承关系用带空心三角形的实线来表示。 关于继承关系一共有两种:普通继承关系和…

【共享模型-----管程】

文章目录 1. 为什么会出现线程安全问题2. synchronized 解决方案2.1 线程八锁 3. 变量的线程安全分析3.1 局部变量线程安全分析3.2 常见线程安全类 1. 为什么会出现线程安全问题 一段代码块内如果存在对共享资源的多线程读写操作,称这段代码块为临界区 共享资源&a…

一张图看懂 8 种网络协议

什么是网络协议? 网络协议就是计算机之间沟通的语言,为了有效地交流,计算机之间需要一种共同的规则或协议,就像我们和老外沟通之前,要先商量好用哪种语言,要么大家都说中文,要么大家都说英语&a…

优思学院|六西格玛将烹饪和美味提升至极致

最近,我们曾提到一个美国男子如何利用六西格玛来控制糖尿病。这表明六西格玛逐渐被认为是一个不仅可以在工作场所之外使用,尤其不仅限于制造业的系统。 六西格玛的核心理念是改进过程的质量,从而改善最终结果。如果你做了晚餐或尝试了一道新…

ESP32设备驱动-OLED显示BME280传感器数据

OLED显示BME280传感器数据 文章目录 OLED显示BME280传感器数据1、BME280介绍2、硬件准备3、软件准备4、代码实现在本文中,我们将介绍如何使用OLED显示BME280传感器的数据。 1、BME280介绍 BME280 传感器用于测量有关环境温度、大气压力和相对湿度的读数。 它主要用于以低功耗…

2023/10/4 -- ARM

今日任务:QT实现TCP服务器客户端搭建的代码,现象 ser: #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);server new QTcpSe…

JMeter性能分析实战一:日常登录接口

负载测试 日常需求:负载测试! 对于桥的负载测试:我给你20t的一排车辆,看你能不能撑得住20t! 对于系统的负载测试: 逐步增加负载,便于问题的发现和定位,不要操之过急。逐步增加负载…

由Long类型引发的生产事故

事情原由 今天测试忽然在群里发了一个看似非常简单的线上问题,具体是:在后台通过订单编号(orderId)修改订单信息时,修改不成功 ,修改前后的订单数据完全没有发生变化。第一眼看到这个问题的时候,我心想后台实现逻辑并不…

CSS 语法

CSS 实例 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: 选择器通常是您需要改变样式的 HTML 元素。 每条声明由一个属性和一个值组成。 属性(property)是您希望设置的样式属性(style attribute&#x…

监狱劳动工具管理系统|智工具DW-S308的功能

监狱劳动工具管理系统(智工具DW-S308)是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对工具进行统一管理、分析的信息化、智能化、规范化的系统。 目前监狱的劳动工具管理很多还停留在固定工位,人盯人、人管人等落后的管理模式&#xff…

图谱滤波(Graph Spectral Processing)-1

时域和空域信号的滤波是图像处理的基本技术之一,迄今已得到广泛的研究。Graph Spectral Processing(GSP)可以处理不规则结构的信号,这些信号在数学上用图形表示。利用谱图理论研究了图信号滤波的理论和方法。在图像处理中,图是表示像素形成的…

华为云云耀云服务器L实例评测|RabbitMQ的Docker版本安装 + 延迟插件安装 QQ邮箱和阿里云短信验证码的主题模式发送

前言 最近华为云云耀云服务器L实例上新,也搞了一台来玩,期间遇到各种问题,在解决问题的过程中学到不少和运维相关的知识。 本篇博客介绍RabbitMQ的Docker版本安装和配置,延迟插件的安装;结合QQ邮箱和阿里云短信验证码…

Gurobi设置初始可行解

目录 1. 决策变量的Start属性直接设置变量的初始值 1.1 Start:MIP变量的起始值(初值)double类型,可更改 1.2 StartNodeLimit:限制了在完善一组输入部分变量的初始解时,MIP所探索的分支定界的节点的数量 …

SAAS软件营销——利用人工智能帮助企业了解客户

软件营销部队(Salesforce)是全球领先的客户关系管理(CRM)解决方案供应商之一,其产品和服务旨在帮助企业成长,并追踪与客户的关系。 在1999 年成立时,它就率先提出了通过互联网(现在通常称为“云”)实现“软件即服务”(SaaS)的概念。 SaaS提…

周期性触发的自定义触发器

背景 本文我们实现一个周期性触发的自定义触发器,顺便看下实现自定义触发器的一些要点 周期性触发器实现 实现一个每分钟触发一次的自定义事件时间触发器,实现代码和注意事项如下所示 package wikiedits.trigger;import org.apache.flink.api.common…

线程通信初始

简单认识一下线程通信 目录 简单认识一下线程通信线程通信定义线程通信模型之一释疑示例案例案例要求案例简单实现 拓展等待和唤醒API 参考视频 注:线程通信 前提是 线程安全 线程通信定义 当多个线程共同操作共享的资源时,线程间通过某种方式互相告知自…

【算法训练-二分查找 三】【特殊二分】寻找峰值

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【数组的二分查找】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为…

Vue3+TS+ECharts5实现中国地图数据信息显示

1.引言 最近在做一个管理系统,主要技术栈使用的是Vue3TSViteElementPlus,主要参考项目是yudao-ui-admin-vue3,其中用到ECharts5做数字大屏,展示中国地图相关信息,以此基础做一个分享,写下这篇文章。 &quo…

解决ASP.NET Core的中间件无法读取Response.Body的问题

概要 本文主要介绍如何在ASP.NET Core的中间件中,读取Response.Body的方法,以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。 代码和实现 现象解释 首先我们尝试在自定义中间件中直接读取Response.Body,代码如…

Appleid苹果账号自动解锁改密(自动解锁二验改密码)

目前该项目能实现以下功能: 多用户使用,权限控制多账号管理账号分享页,支持设置密码、有效期、自定义HTML内容自动解锁与关闭二步验证自动/定时修改密码自动删除Apple ID中的设备代理池与Selenium集群,提高解锁成功率允许手动触发…