三十的博客

GVM 脚手架探险记02:那些让我拍大腿的Go技巧彩蛋

发布时间
阅读量 加载中...

正确的快速的初始化环境

打开 GVM 项目的 main.go 文件,首先就是可以看到如下代码注释

//go:generate go env -w GO111MODULE=on
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
//go:generate go mod tidy
//go:generate go mod download

这些是 Go 语言的 //go:generate 指令,它们用于在构建前自动执行一些准备工作。

//go:generate go env -w GO111MODULE=on

​作用​:设置 Go 模块模式为开启状态

​详细解释​:GO111MODULE 是 Go 1.11 引入的环境变量,控制模块支持。设置为 on 表示强制启用 Go 模块模式。-w 表示将设置写入环境变量(持久化)。

//go:generate go env -w GOPROXY=https://goproxy.cn,direct

作用​:设置 Go 模块代理

​详细解释​:GOPROXY 指定从哪里下载 Go 模块。https://goproxy.cn 是中国的一个 Go 模块镜像,可以加速国内下载。direct 表示如果代理找不到,直接从版本控制系统(如 GitHub)下载。多个地址用逗号分隔,会按顺序尝试。

//go:generate go mod tidy

作用​:整理和同步模块依赖

​详细解释​:添加项目需要的但缺失的依赖。移除项目不再使用的依赖。更新 go.mod 和 go.sum 文件。

//go:generate go mod download

作用​:下载模块依赖到本地缓存

详细解释​:下载 go.mod 文件中指定的所有依赖。下载的模块会存储在 $GOPATH/pkg/mod 目录下。

指令执行方式: go generate

扩展的时间解析方法

GVM 脚手架中使用了自定义的时间解析方法,支持解析包含天的时长字符串,
如 “3d”、“2d6h30m”。

go
// utils/human_duration.go

package utils

import (
	"strconv"
	"strings"
	"time"
)

// ParseDuration 自定义的解析时间的方法
// 支持解析包含天的时长字符串,如 "3d"、"2d6h30m"
func ParseDuration(d string) (time.Duration, error) {
	// 去除字符串首尾空格
	d = strings.TrimSpace(d)
	// 尝试用标准库解析
	dr, err := time.ParseDuration(d)
	if err == nil {
		return dr, nil
	}
	// 当字符串包含 "d" 时,将其视为天单位
	if strings.Contains(d, "d") {
		index := strings.Index(d, "d")

		hour, _ := strconv.Atoi(d[:index])
		dr = time.Hour * 24 * time.Duration(hour)
		ndr, err := time.ParseDuration(d[index+1:])
		if err != nil {
			return dr, nil
		}
		return dr + ndr, nil
	}

	// 尝试将输入解析为整数
	dv, err := strconv.ParseInt(d, 10, 64)
	// 直接转换为 time.Duration 类型(单位为纳秒)
	return time.Duration(dv), err
}
🚀 类型说明
time.Duration​ → 用于表示 ​时间间隔​(如 5s、2h),适合计算时间差、延时等。
time.Time​ → 用于表示 ​具体时间点​(如 2023-10-01 12:00:00),适合存储和操作日期时间。

利用 mod 配置文件配置模块名

可以参考读取配置文件的思想来做一些配置默认值。

go
// initialize/other.go

// 尝试打开当前目录下的 go.mod 文件
file, err := os.Open("go.mod")
if err == nil && global.GVA_CONFIG.AutoCode.Module == "" {
	defer file.Close() // 确保文件被关闭
	// bufio.NewScanner(file) 创建一个 Scanner 文件扫描器,用于逐行读取文件内容
	scanner := bufio.NewScanner(file)
	// scanner.Scan() 读取文件的下一行(这里只读取第一行)。
	scanner.Scan()
	// scanner.Text() 返回当前行的内容
	global.GVA_CONFIG.AutoCode.Module = strings.TrimPrefix(scanner.Text(), "module ")
}
#Gvm #Golang