【Go 编程实践】从零到一:创建、测试并发布自己的 Go 库

news2024/11/23 13:07:53

为什么需要开发自己的 Go 库

在编程语言中,包(Package)和库(Library)是代码组织和复用的重要工具。在 Go 中,包是代码的基本组织单位,每个 Go 程序都由包构成。包的作用是帮助组织代码,提供封装和代码复用的机制。

Go 包可以包含函数、类型、变量和常量等,这些元素可以被其他包引用和使用。例如,Go 的标准库提供了大量的包,如 net/http 包提供了 HTTP 客户端和服务器实现,fmt 包提供了格式化、I/O 函数等。

而库是一种特殊的包,不包含 main 函数,不能被直接运行,但可以被其他程序引用。库通常包含一些常用的功能或算法,如字符串处理、数学计算、网络通信等。

开发自己的 Go 库的优点:

  1. 复用性:当在多个项目中需要使用相同的功能时,可以将这些功能封装在一个库中,然后在需要的地方引用他。这样可以避免重复编写相同的代码,提高编程效率。
  2. 可维护性:当需要修改某个功能时,只需修改对应的库,而不需要在多个地方进行修改,这样可以使代码更易于理解和维护。
  3. 可测试性:为每个库编写单元测试,确保他们的功能正确。修改代码时,可以运行这些测试来检查是否引入了新的错误。

接下来,将以 Asiatz(github.com/mazeyqian/asiatz)为例,详细演示如何创建一个规范的 Go 库。

Asiatz 主要功能是进行时区转换,特别是对亚洲时区的处理,他能够将各种时区转换为 UTC 时间。

utcTime, err := asiatz.ShanghaiToUTC("08:00")
if err != nil {
    // handle error
}
fmt.Println(utcTime) // Output: 00:00

第 1 步:创建目录

在本地创建一个新的目录,名为 asiatz。这个目录将包含所有的源代码、测试和文档文件。

mkdir asiatz
cd asiatz

第 2 步:初始化项目

2.1 初始化 Go 模块

asiatz 目录下,运行 go mod init <domain>/<username>/<module-name> 来初始化 Go 模块。

go mod init github.com/mazeyqian/asiatz

项目结构:

asiatz
└── go.mod

2.2 创建文件

创建一个新的 Go 文件,名为 asiatz.go。在此文件中,定义一个名为 asiatz 的包,并编写相对应的功能函数。

项目结构:

asiatz
├── asiatz.go
└── go.mod

代码示例:

package asiatz

import (
    "fmt"
    "strconv"
)

// ToUTC converts a time string (HH:mm) from a specified timezone to UTC time string (HH:mm).
func ToUTC(timezoneOffset float64, time string) (string, error) {
    hour, err := strconv.Atoi(time[:2])
    if err != nil {
        return "", err
    }
    minute, err := strconv.Atoi(time[3:])
    if err != nil {
        return "", err
    }
    totalMinutes := hour*60 + minute
    utcTotalMinutes := ((totalMinutes-int(timezoneOffset*60))%1440 + 1440) % 1440
    utcHour := utcTotalMinutes / 60
    utcMinute := utcTotalMinutes % 60
    utcTime := fmt.Sprintf("%02d:%02d", utcHour, utcMinute)
    return utcTime, nil
}

// ShanghaiToUTC converts a Shanghai time string (HH:mm) to UTC time string (HH:mm).
// For example, "08:00" in Shanghai is equivalent to "00:00" in UTC.
func ShanghaiToUTC(shanghaiTime string) (string, error) {
    return ToUTC(8, shanghaiTime)
}

第 3 步:编写测试

Go 提供了内置的测试框架,可以方便地编写和运行测试用例,以确保代码的正确性和稳定性。

asiatz 目录下创建一个新的 Go 文件,名为 asiatz_test.go。在这个文件中编写测试用例来测试 asiatz.go 中的函数。

项目结构:

asiatz
├── asiatz.go
├── asiatz_test.go
└── go.mod

代码示例:

package asiatz

import "testing"

type testConversion struct {
    time     string
    expected string
}

var tests = map[string][]testConversion{
    "Shanghai": {
        {"01:00", "17:00"},
        {"23:59", "15:59"},
    },
    // Others
}

func runConversionTests(t *testing.T, tests []testConversion, conversionFunc func(string) (string, error)) {
    for _, test := range tests {
        actual, err := conversionFunc(test.time)
        if err != nil {
            t.Errorf("Unexpected error for %s: %v", test.time, err)
            continue
        }
        if actual != test.expected {
            t.Errorf("Expected %s for %s but got %s", test.expected, test.time, actual)
        }
    }
}

func TestAllConversions(t *testing.T) {
    for timezone, tests := range tests {
        t.Run(timezone, func(t *testing.T) {
            switch timezone {
            case "Shanghai":
                runConversionTests(t, tests, ShanghaiToUTC)
            // Others
            default:
                t.Errorf("Unexpected timezone %s", timezone)
            }
        })
    }
}

查看完整的用例可见:github.com/mazeyqian/asiatz/blob/main/asiatz_test.go

在当前目录下运行 go test 查看结果:

PASS
ok      github.com/mazeyqian/asiatz     0.449s

第 4 步:编写文档

为了方便其他人理解和使用 Asiatz 库,需要编写相应的使用文档。文档应包括库的目的、功能函数的用法、使用示例和注意事项等。

asiatz 目录下,创建一个新的 README.md 文件,并在其中编写文档。

项目结构:

asiatz
├── asiatz.go
├── asiatz_test.go
├── go.mod
└── README.md

文档示例:

文档示例

第 5 步:发布

5.1 上传

上传到 GitHub

将 Asiatz 库上传到 GitHub 或其他代码托管平台,使其他人可以方便地获取和使用。

go get github.com/mazeyqian/asiatz

5.2 版本控制

标签

在 Git 仓库上,还可以使用标签来管理库的不同版本。

git tag v1.0.0
git push origin v1.0.0

例如 Asiatz 目前有四个版本:v1.0.0v1.1.0v1.1.1v1.1.2,分别可以用以下命令获取:

go get github.com/mazeyqian/asiatz@v1.0.0
go get github.com/mazeyqian/asiatz@v1.1.0
go get github.com/mazeyqian/asiatz@v1.1.1
go get github.com/mazeyqian/asiatz@v1.1.2

第 6 步:在真实项目中使用

以 Go 项目 github.com/mazeyqian/go-gin-gee 为例,首先在项目目录(go-gin-gee)下运行命令 go get github.com/mazeyqian/asiatz 获取 Asiatz 库,然后引入使用即可:

// https://github.com/mazeyqian/go-gin-gee/blob/main/internal/api/controllers/schedules-controller.go
package controllers

import (
    "log"
    "github.com/mazeyqian/asiatz"
)

func Check() {
    // ...
    utcTime, err := asiatz.ShanghaiToUTC("10:00")
    if err != nil {
        // handle error
    }
    log.Println("UTC Time:", utcTime) // Output: 02:00
    // ...
}

总结

本文以 Asiatz 库为例,详细演示了如何从零开始创建、测试并发布自己的 Go 库。无论是新手,还是有经验的开发者;动手实践,开发并发布自己的库,不仅可以提高代码的复用性和维护性,提高自己的技能,还可以为社区做出贡献。

版权声明

本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者后除和本文原始地址:https://blog.mazey.net/4150.html

(完)

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

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

相关文章

高等数学教材重难点题型总结(十二)无穷级数

最后一更&#xff01;原谅博主已经开始瞎写字了&#xff0c;最近压力太大&#xff0c;以后有时间用mathPix打出来&#xff0c;看起来更舒适一些~ 高数最后一章&#xff0c;重点在于审敛法和求解幂级数的收敛半径~ 高数基础笔记全部更新完毕&#xff0c;共12*336期&#xff0c…

【qemu逃逸】华为云2021-qemu_zzz

前言 虚拟机用户名&#xff1a;root 无密码 设备逆向 经过逆向分析&#xff0c;可得实例结构体大致结构如下&#xff1a; 其中 self 指向的是结构体本身&#xff0c;cpu_physical_memory_rw 就是这个函数的函数指针。arr 应该是 PCI 设备类结构体没啥用&#xff0c;就直接用…

动态规划算法实现0-1背包问题Java语言实现

问题介绍&#xff1a; 动态规划算法&#xff1a; 动态规划&#xff08;Dynamic Programming&#xff09;是一种解决多阶段决策问题的优化算法。它通过将问题分解为一系列子问题&#xff0c;并利用子问题的解来构建更大规模问题的解&#xff0c;从而实现对整个问题的求解。 动态…

五子棋对战测试报告

目录 一、项目背景 二、项目功能 三、功能测试 1、注册页面测试 测试用例 测试结果 测试总结 2、登录页面测试 测试用例 测试结果 测试总结 3、游戏大厅页面测试 测试用例 测试结果 测试总结 4、游戏房间页面测试 测试用例 测试结果 测试总结 一、项目背景 …

物联网AI MicroPython传感器学习 之 无源蜂鸣器

一、产品简介 蜂鸣器是一种将音频信号转化为声音信号的发音器件传感器&#xff0c;通过利用压电效应原理&#xff0c;当对其施加交变电压时产生机械振动。应用场景&#xff1a;在家用电器、电子玩具、游戏机等场景下都得到普遍应用&#xff0c;通过设置不同的频率&#xff0c;…

Linux下yum源配置实战

一、Linux下软件包的管理 1、软件安装方式 ① RPM包管理&#xff08;需要单独解决依赖问题&#xff09; ② YUM包管理&#xff08;需要有网络及YUM仓库的支持&#xff0c;会自动从互联网下载软件&#xff0c;自动解决依赖&#xff09; ③ 源码安装&#xff08;安装过程比较…

前端面试题之CSS篇

1、css选择器及其优先级 标签选择器: 1类选择器、属性选择器、伪类选择器&#xff1a;10id选择器&#xff1a;100内联选择器&#xff08;style“”&#xff09;&#xff1a;1000!important&#xff1a;10000 2、display的属性值及其作用 属性值作用none元素不显示&#xff0c…

数据分析实战 | 关联规则分析——购物车分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据预处理 七、生成频繁项集 八、计算关联度 九、可视化 一、数据及分析对象 数据集链接&#xff1a;Online Retail.xlsx 该数据集记录了2010年12月01日至2011年12月09日…

【深蓝学院】手写VIO第8章--相机与IMU时间戳同步--作业

0. 题目 1. T1 逆深度参数化时的特征匀速模型的重投影误差 参考常鑫助教的答案&#xff1a;思路是将i时刻的观测投到world系&#xff0c;再用j时刻pose和外参投到j时刻camera坐标系下&#xff0c;归一化得到预测的二维坐标&#xff08;这里忽略了camera的内参&#xff0c;逆深…

力扣刷题之优先队列

前言&#xff1a;优先队列底层是由大根堆或小根堆数据结构实现的。 前K个高频元素 347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: …

基于LDA主题+协同过滤+矩阵分解算法的智能电影推荐系统——机器学习算法应用(含python、JavaScript工程源码)+MovieLens数据集(四)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据爬取及处理2. 模型训练及保存3. 接口实现4. 收集数据5. 界面设计 系统测试相关其它博客工程源代码下载其它资料下载 前言 前段时间&#xff0c;博主分享过关于一篇使用协同过滤算法进行智能电影推荐系统的博…

CCF-CSP真题《202305-5 闪耀巡航》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202305-5试题名称&#xff1a;闪耀巡航时间限制&#xff1a;5.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 西西艾弗岛旅游公司最近推出了一系列环绕西西艾…

周报4_YMK

FlashAttention 硬件知识 以 A100 (40GB HBM) 为例&#xff0c;下面显示其内存层次结构的粗略图。SRAM内存分布在108个流式多处理器(SMs)上&#xff0c;每个处理器192KB。片上SRAM比HBM快得多&#xff0c;但比HBM小得多&#xff0c;在计算方面&#xff0c;使用Tensor Core的B…

【ARFoundation学习笔记】ARFoundation基础(上)

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 本文从原文第二章开始 文章目录 ARFoundation的体系Subsystem的使用跟踪子系统 ARSession & AR Session OriginARSessionARSe…

多目标优化中的“latent action”是什么?

2020 NeurIPS 中的“latent action”&#xff1a; Our model defines latent action as a boundary that splits the region represented by a node into a high-performing and a low performing region. 这里的latent action代表一个边界&#xff08;分类器&#xff09;&…

4 网络基础知识

1、 ifconfig&#xff1a; 1.Windows&#xff1a;ipconfig 2.Linux&#xff1a;ifconfigip addr2、 ifconfig 和 ip addr 的区别&#xff1f; 问题&#xff1a;假设你登录进入一个被裁剪过的非常小的 Linux 系统中&#xff0c;发现既没有 ifconfig 命令&#xff0c;也没有 ip…

CCF-CSP真题《202309-2 坐标变换(其二)》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202309-2试题名称&#xff1a;坐标变换&#xff08;其二&#xff09;时间限制&#xff1a;2.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 对于平面直角坐标…

【Mybatis小白从0到90%精讲】13: Mybatis sql片段,重用SQL的利器!

文章目录 前言SQL片段语句常见应用场景1. select 列字段2. where条件前言 代码复用是优秀程序员的标志之一,它能够减少代码冗余,提高代码可读性和可维护性。 在MyBatis开发中,Mapper中经常会有一些类似的SQL,如果每个语句都单独编写,会使代码冗长且难以维护。 MyBatis提…

Magics测量两个圆形中心点距离的方法

摘要&#xff1a;本文介绍如何使用magics测量两个圆孔之间的距离。 问题来源&#xff1a;3D模型打开后&#xff0c;两个圆孔中心点之间的间距测量无法直接通过测距实现&#xff0c;需要进行一些小小的设置才行。 工具选择“量尺”&#xff0c;如果不设置的话&#xff0c;它会默…

有关我自贡大盐商身世的两篇文章(一)

重游高坑岩瀑布随笔 都市噪杂喧嚣的生活&#xff0c;终于将我暂时逼离网络&#xff0c;决意出游数日&#xff0c;去山里寻找我向往的那些足以鼓舞人斗志的壮观瀑布&#xff0c;并试图从中领受它们那出自天然的&#xff0c;万马奔腾、猛烈撞击、拚抢速度、渲泄激情、永不妥协、…