You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用github.com/mitchellh/mapstructure将结构体编码为指定格式map?

解决mapstructure将timestamppb.Timestamp转为字符串格式的问题

问题根源

你之前的错误是混淆了mapstructure的**解码(Decode)与编码(Encode)**方向:默认的DecodeHook用于将map转成结构体的场景,而你需要把结构体转成map,属于编码流程,必须用EncodeHook处理类型转换,同时覆盖timestamppb.Timestamp默认转map的行为。

实现方案

通过EncodeHookFunc结合反射,实现*timestamppb.Timestamp字段转指定格式字符串的逻辑,完整代码如下:

package main

import (
	"fmt"
	"reflect"
	"time"

	"github.com/golang/protobuf/ptypes/timestamp"
	"github.com/mitchellh/mapstructure"
)

type Struct struct {
	CreateDate *timestamp.Timestamp `mapstructure:"create_date"`
}

// TimestampToStringHook 将*timestamppb.Timestamp格式化为"2006-01-02 15:04:05"字符串
func TimestampToStringHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
	// 仅处理从*timestamppb.Timestamp到string的转换(编码方向)
	if f == reflect.TypeOf(&timestamp.Timestamp{}) && t.Kind() == reflect.String {
		ts := data.(*timestamp.Timestamp)
		return ts.AsTime().Format("2006-01-02 15:04:05"), nil
	}
	// 其他类型不做处理,返回原数据
	return data, nil
}

func main() {
	// 构造测试结构体实例
	s := Struct{
		CreateDate: &timestamp.Timestamp{
			Seconds: time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC).Unix(),
		},
	}

	// 配置解码器,核心是设置EncodeHook
	var result map[string]any
	config := &mapstructure.DecoderConfig{
		Result:  &result,
		TagName: "mapstructure",
		EncodeHook: mapstructure.ComposeEncodeHookFunc(
			TimestampToStringHook,
		),
	}

	decoder, err := mapstructure.NewDecoder(config)
	if err != nil {
		panic(err)
	}

	// 执行结构体到map的转换
	if err := decoder.Decode(s); err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", result)
	// 输出:map[string]interface {}{"create_date":"2024-01-01 12:00:00"}
}

关键说明

  1. 钩子方向匹配:通过判断源类型为*timestamppb.Timestamp、目标类型为string,确保只处理我们需要的转换场景,不干扰其他类型的默认处理。
  2. EncodeHook的作用:DecoderConfig中的EncodeHook专门负责结构体转map时的类型转换,而你之前误用的DecodeHook是map转结构体时的钩子,这是报错的核心原因。
  3. 时间格式化逻辑:借助timestamppb.Timestamp的AsTime()方法转成Go标准time.Time类型,再用Format()生成指定格式的字符串。

内容的提问来源于stack exchange,提问作者MrDan4es

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:58:16