前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Go 编程实践】从零到一:创建、测试并发布自己的 Go 库

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

原创
作者头像
后除
修改2023-10-23 11:02:41
7340
修改2023-10-23 11:02:41
举报
文章被收录于专栏:后除的专栏后除的专栏

为什么需要开发自己的 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 时间。

代码语言:go
复制
utcTime, err := asiatz.ShanghaiToUTC("08:00")
if err != nil {
    // handle error
}
fmt.Println(utcTime) // Output: 00:00

第 1 步:创建目录

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

代码语言:shell
复制
mkdir asiatz
cd asiatz

第 2 步:初始化项目

2.1 初始化 Go 模块

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

代码语言:shell
复制
go mod init github.com/mazeyqian/asiatz

项目结构:

代码语言:text
复制
asiatz
└── go.mod

2.2 创建文件

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

项目结构:

代码语言:text
复制
asiatz
├── asiatz.go
└── go.mod

代码示例:

代码语言:go
复制
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 中的函数。

项目结构:

代码语言:text
复制
asiatz
├── asiatz.go
├── asiatz_test.go
└── go.mod

代码示例:

代码语言:go
复制
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 查看结果:

代码语言:text
复制
PASS
ok      github.com/mazeyqian/asiatz     0.449s

第 4 步:编写文档

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

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

项目结构:

代码语言:text
复制
asiatz
├── asiatz.go
├── asiatz_test.go
├── go.mod
└── README.md

文档示例:

文档示例
文档示例

第 5 步:发布

5.1 上传

上传到 GitHub
上传到 GitHub

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

代码语言:shell
复制
go get github.com/mazeyqian/asiatz

5.2 版本控制

标签
标签

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

代码语言:shell
复制
git tag v1.0.0
git push origin v1.0.0

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

代码语言:shell
复制
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 库,然后引入使用即可:

代码语言:go
复制
// 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 库。无论是新手,还是有经验的开发者;动手实践,开发并发布自己的库,不仅可以提高代码的复用性和维护性,提高自己的技能,还可以为社区做出贡献。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么需要开发自己的 Go 库
  • 第 1 步:创建目录
  • 第 2 步:初始化项目
    • 2.1 初始化 Go 模块
      • 2.2 创建文件
      • 第 3 步:编写测试
      • 第 4 步:编写文档
      • 第 5 步:发布
        • 5.1 上传
          • 5.2 版本控制
          • 第 6 步:在真实项目中使用
          • 总结
          相关产品与服务
          代码托管
          CODING 代码托管(CODING Code Repositories,CODING-CR)是为开发者打造的云端便捷代码管理工具,旨在为更多的开发者带去便捷、高效的开发体验,全面支持 Git/SVN 代码托管,包括代码评审、分支管理、超大仓库等功能。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档


          http://www.vxiaotou.com