将时间字段编组为Unix时间

huangapple go评论81阅读模式
英文:

Marshalling Time fields as Unix time

问题

我想将我的time.Time字段编码为数字的Unix时间戳,并且我不想为每个结构体实现自定义的MarshalJSON函数,因为我有很多很多的结构体。

所以,我尝试定义一个类型别名,如下所示:

type Timestamp time.Time

并在其上实现MarshalJSON,如下所示:

func (t Timestamp) MarshalJSON() ([]byte, error) {
    return []byte(strconv.FormatInt(t.Unix(), 10)), nil
}

但是这给我一个错误:t.Unix undefined (type Timestamp has no field or method Unix),这对我来说没有意义。难道Timestamp不应该"继承"(我知道这可能是错误的术语)time.Time的所有函数吗?

我还尝试使用类型断言,如下所示:

strconv.FormatInt(t.(time.Time).Unix(), 10)

但这也失败了,报错说类型断言无效:invalid type assertion: t.(time.Time) (non-interface type Timestamp on left)

英文:

I want to encode my time.Time fields as numeric Unix time and I would prefer not to implement custom MarshalJSON functions for each and every struct, since I have lots and lots of structs.

So, I tried defining a type alias as such:

type Timestamp time.Time

And implementing MarshalJSON on it like so:

func (t Timestamp) MarshalJSON() ([]byte, error) {
    return []byte(strconv.FormatInt(t.Unix(), 10)), nil
}

But that gives me a t.Unix undefined (type Timestamp has no field or method Unix), which doesn't make sense to me. Shouldn't Timestamp 'inherit' (I know that's probably the wrong term) all functions of time.Time?

I also tried using a type assertion like so:

strconv.FormatInt(t.(time.Time).Unix(), 10)

But that also fails, complaining about an invalid type assertion: invalid type assertion: t.(time.Time) (non-interface type Timestamp on left)

答案1

得分: 1

你需要将类型转换回time.Time,以便访问其方法。命名类型不会“继承”其基础类型的方法(要实现这一点,你需要使用嵌入)。

func (t Timestamp) MarshalJSON() ([]byte, error) {
    return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
}

另外,就个人偏好而言,我更倾向于使用fmt.Sprintf("%v", i)而不是strconv.FormatInt(i, 10)或者strconv.Itoa(i)。老实说,我不确定哪个更快,但是fmt版本在阅读上更容易理解,就我个人而言。

英文:

You need to convert your type back to a time.Time to have access to its methods. Named types do not "inherit" the methods of their underlying types (to do that, you need embedding).

func (t Timestamp) MarshalJSON() ([]byte, error) {
    return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
}

Also, just as a matter of personal preference, I tend to preferred fmt.Sprintf("%v", i) over strconv.FormatInt(i, 10) or even strconv.Itoa(i). Honestly not sure which is faster, but the fmt version seems easier to read, personally.

huangapple
  • 本文由 发表于 2016年12月14日 05:41:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/41131041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定