Why is time in Go printed differently in a struct?

断了今生、忘了曾经 提交于 2021-02-07 20:33:20

问题


I'm just starting out with Go, and in the first program I wrote I printed out a struct, which also showed

{wall:0 ext:63533980800 loc:<nil>}

Being puzzled over what that was it seemed to be a type time.Time(), and a google search brought me to this part of the Go source code in which the difference between the "wall clock" and the "monotonic clock" is explained in the comments.

So to test it in isolation I created a new minimalistic program:

package main

import (
    "fmt"
    "time"
)

type TheStruct struct {
    the_time time.Time
}

func main() {
    the_struct := TheStruct{time.Now()}
    fmt.Println(the_struct)
    fmt.Printf("%+v\n", the_struct)
    fmt.Println(the_struct.the_time)
    fmt.Println()
    the_struct_2 := TheStruct{time.Unix(1505099248, 200)}
    fmt.Println(the_struct_2)
    fmt.Printf("%+v\n", the_struct_2)
    fmt.Println(the_struct_2.the_time)
}

which prints out the following:

{{13719544904843884912 534246 0x1140680}}
{the_time:{wall:13719544904843884912 ext:534246 loc:0x1140680}}
2017-09-11 05:08:11.35635032 +0200 CEST m=+0.000534246

{{200 63640696048 0x1140680}}
{the_time:{wall:200 ext:63640696048 loc:0x1140680}}
2017-09-11 05:07:28 +0200 CEST

So I wonder about two things here:

  1. Why is the time if part of a struct printed as wall clock as compared to the more usual datetime notation when printed out separately (using the_struct.the_time)?
  2. Is it a problem that the code in my other program prints out <nil> for the loc? How would I be able to solve that?

回答1:


The reason why it's not printing the formatted time when in your struct is that String method is not invoked on the unexported fields (refer https://golang.org/pkg/fmt/):

When printing a struct, fmt cannot and therefore does not invoke formatting methods such as Error or String on unexported fields.

Changing your structure to export fields (capitalizing the first letter) makes it invoke the String method:

   package main

import (
    "fmt"
    "time"
)

type TheStruct struct {
    The_time time.Time
}

func main() {
    the_struct := TheStruct{time.Now()}
    fmt.Println(the_struct)
    fmt.Printf("%+v\n", the_struct)
    fmt.Println(the_struct.The_time)
    fmt.Println()
    the_struct_2 := TheStruct{time.Unix(1505099248, 200)}
    fmt.Println(the_struct_2)
    fmt.Printf("%+v\n", the_struct_2)
    fmt.Println(the_struct_2.The_time)
}

Output:

{2009-11-10 23:00:00 +0000 UTC m=+0.000000000}
{The_time:2009-11-10 23:00:00 +0000 UTC m=+0.000000000}
2009-11-10 23:00:00 +0000 UTC m=+0.000000000

{2017-09-11 03:07:28.0000002 +0000 UTC}
{The_time:2017-09-11 03:07:28.0000002 +0000 UTC}
2017-09-11 03:07:28.0000002 +0000 UTC

On playground : https://play.golang.org/p/r0rQKBlpWc




回答2:


The other answer covers the first part of your question quite well, so I will only cover the second part here.

To put it simply, no, a nil location is not a problem, as acording to the source code for time.Time, a nil location means UTC.

// loc specifies the Location that should be used to
// determine the minute, hour, month, day, and year
// that correspond to this Time.
// The nil location means UTC.
// All UTC times are represented with loc==nil, never loc==&utcLoc.
loc *Location


来源:https://stackoverflow.com/questions/46147641/why-is-time-in-go-printed-differently-in-a-struct

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!