指针的使用
指针是一种强大的工具,在日常开发中有多种巧妙用途。虽然我在 Delphi/Lazarus 中已经能熟练运用,但在 Go 语言中却屡次遇到问题。
空指针问题
空指针是近期遇到最多的问题,稍有不慎就会引发程序崩溃,带来不少困扰。经过多次实践,总结出以下几点经验:
- 在可以使用值类型的情况下,尽量避免使用指针类型,除非确实需要指针的场景
- 避免仅使用
var p *T声明指针变量,应在声明时立即进行初始化,除非确实需要初始值为nil - 在使用指针变量前,务必进行空值检查
指针赋值
目前在 Go 语言(go1.25.x 版本)中,不能直接将字面量赋值给指针变量。需要先将字面量赋值给变量,再获取该变量的地址赋值给指针变量,例如:
n := 0
p := &n
时间处理
字符串时间解析
将字符串时间转换为 time.Time 类型是常见操作,通常使用 time.Parse 方法实现。但必须确保时间格式与字符串时间的格式完全匹配。可以通过自定义函数来实现多种格式的兼容:
func parseTime(timeStr string) (time.Time, error) {
// 尝试多种时间格式
layouts := []string{
"2006-01-02 15:04:05",
"2006/01/02 15:04:05",
"2006-01-02",
time.RFC3339,
"02/01/2006 15:04:05",
}
for _, layout := range layouts {
if t, err := time.Parse(layout, timeStr); err == nil {
return t, nil
}
}
return time.Time{}, fmt.Errorf("无法解析时间: %s", timeStr)
}
时区处理
在大多数情况下,时区问题可以忽略不计。但当字符串时间中包含时区信息时,就必须认真处理时区相关问题。
time.Parse方法返回的是 UTC 时间time.ParseInLocation方法返回的是指定时区的时间time.LoadLocation方法用于加载特定时区
在容器环境中使用
基于alpine、scratch等轻量级镜像默认不包含时区数据文件,因此无法正常调用time.LoadLocation等依赖时区信息的函数。可通过以下方案解决:
-
构建镜像时安装时区数据库
# Dockerfile FROM alpine:latest # 安装时区数据包 RUN apk add --no-cache tzdata # 设置默认时区(可选) ENV TZ=Asia/Shanghai # 验证时区文件是否存在 RUN ls -la /usr/share/zoneinfo/ # 复制应用程序 COPY app /app CMD ["/app"] -
通过源码导入时区数据(适用于Go 1.15及以上版本)
// 仅在主入口包中导入 import ( "time" _ "time/tzdata" // 注意需在time包之后导入 ) // 需注意避免重复导入,尤其在库包中应谨慎使用
异常处理
程序在运行过程中可能触发panic,若未进行捕获将导致进程异常终止。建议在主函数或主请求处理流程中加入恢复机制,捕获后应记录详细的堆栈信息,便于问题排查。
defer func() {
if r := recover(); r != nil {
// 打印调用堆栈
debug.PrintStack()
// 也可将panic转换为error返回,例如在具体函数内部处理
// 若需进一步处理可重新抛出,例如日志中间件仅记录不干预
panic(r)
}
}()

随时随地看视频