为了账号安全,请及时绑定邮箱和手机立即绑定

打印时间时出现意外输出。时间类型别名

打印时间时出现意外输出。时间类型别名

Go
萧十郎 2022-12-26 16:43:19
我正在尝试为自定义类型编写解组函数。考虑以下代码(游乐场)package mainimport (    "encoding/json"    "fmt"    "strings"    "time")type Time time.Timefunc (st *Time) UnmarshalJSON(b []byte) error {    // "2021-05-21T03:10:20.958450" -> "2021-05-21T03:10:20.958450Z"    s := strings.Trim(string(b), "\"")    t, err := time.Parse(time.RFC3339, fmt.Sprintf("%s%s", s, "Z"))    if err != nil {        return fmt.Errorf("parse time: %w", err)    }    *st = Time(t)    return nil}type User struct {    Name string    TS Time}const data = `{"id":3, "name":"Name", "ts":"2021-05-21T03:10:20.958450"}`func main() {    user := new(User)    json.Unmarshal([]byte(data), &user)    fmt.Printf("%v\n", user)}我成功地time.Time从我那里得到了一个有效的价值,time.Parse()但我不太明白为什么要*st = Time(t)给出如此奇怪的价值?目前上面打印出来:&{Name {958450000 63757163420 <nil>}}但我想更类似于:&{Name 2021-05-21 03:10:20.95845 +0000 UTC}我在这里误解了什么?
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

与 time.Time 相反,你的类型没有实现fmt.Stringer,所以 fmt.Print* 函数别无选择,只能使用它们的默认格式化逻辑,在这种情况下是打印底层 time.Time 值的字段大括号。


将委托给 time.Time.String 的 String 方法添加到您的类型以获得所需的行为:


func (t Time) String() string {

    return time.Time(t).String()

}

https://go.dev/play/p/5PwOwa49B5X


或者,将您的时间类型更改为嵌入 time.Time。这将自动提升 String 方法以及所有其他方法(例如 Marshal* 方法):


type Time struct {

    time.Time

}


func (st *Time) UnmarshalJSON(b []byte) error {

    // ...

    st.Time = t // simple assignment without type conversion

    return nil

}

https://go.dev/play/p/0H5qyCO22gu


此外,您永远不应该手动解析 JSON。strings.Trim(string(b), "\"")不足以完全解码 JSON 字符串值。始终使用 json.Unmarshal。您可以使用 time.ParseInLocation 来简化。


func (st *Time) UnmarshalJSON(b []byte) error {

    var s string

    if err := json.Unmarshal(b, &s); err != nil {

        return err

    }


    t, err := time.ParseInLocation("2006-01-02T15:04:05", s, time.UTC)

    if err != nil {

        return err

    }


    // ...

}


查看完整回答
反对 回复 2022-12-26
  • 1 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号