unmarshaljson中的golang类型转换

时间:2014-09-18 02:38:45

标签: go

有人能帮助我,请问这里出了什么问题?出于某种原因输出不一样,我不明白为什么。

type rTime time.Time

func (rt *rTime) UnmarshalJSON(data []byte) error {
    var s string
    if err := json.Unmarshal(data, &s); err != nil {
        return err
    }

    t, err := time.Parse("2006-01-02", s)
    if err != nil {
        return err
    }
    log.Println(t)

    *rt = rTime(t)

    log.Println(*rt)
    return nil
}

日志看起来像这样:

2014/09/18 04:31:35 1999-10-15 00:00:00 +0000 UTC
2014/09/18 04:31:35 {63075542400 0 0x933ea0}

为什么转换不起作用?输入字符串为1995-10-15 btw。

1 个答案:

答案 0 :(得分:3)

转换正常,但fmt.Println()会查找String()方法,该方法存在于time.Time上,但不存在于您的类型上。您只需要func (rt rTime) String() string { return time.Time(rt).String() }就可以将String()个电话转回time.Time的实施。

Here's an example

package main

import (
    "log"
    "time"
)

type rTime time.Time

func (rt rTime) String() string { return time.Time(rt).String() }

func main() {
    s := "1999-10-15"
    t, err := time.Parse("2006-01-02", s)
    if err != nil {
        panic(err)
    }
    log.Println(t)

    rt := rTime(t)

    log.Println(rt)
}

请注意,我将这两种时间类型都视为值the standard library does,每the canonical advice to avoid pointers for tiny structs with value semantics

也许更有趣的是,您可以使用type embedding自动获取time.Time的所有方法,除非您覆盖任何方法。语法略有变化(see on Playground):

package main

import (
    "log"
    "time"
)

type rTime struct { time.Time }

func main() {
    s := "1999-10-15"
    t, err := time.Parse("2006-01-02", s)
    if err != nil {
        panic(err)
    }
    log.Println(t)

    rt := rTime{t}

    log.Println(rt)
}

如果你已经使用了嵌入并希望编写自己的自定义方法,这些方法可以“代理”到嵌入式类型,那么你可以使用像obj.EmbeddedTypeName.Method这样的语法,它可能是这样的,例如,rt.Time.String()

// a custom String method that adds smiley faces
func (rt rTime) String() string { return " " + rt.Time.String() + " "  }

obj.EmbeddedTypeName也是您(例如)访问您嵌入的非struct类型的运算符的方式。