3

I'm trying to use a time.Time structure in a structure that will be encoded/decoded with JSON. The time.Time attributes should not be included if they aren't set (omitempty tag), so to be able to do so I will have to use a pointer to the time.Time object.

I have defined a type for the time.Time structure so I easily can create receiver functions format the time when the JSON is encoded and decoded etc.

See the code here: https://play.golang.org/p/e81xzA-dzz

So in my main structure (the structure that actually will be encoded) I will do something like this:

type EncodeThis struct {
   Str string `json:"str,omitempty"`
   Date *jWDate `json:"date,omitempty"`
}

The problem is that the pointer may be nil, when trying to decode the value, so if you look at my code at the Go playground, you can see that I'm trying to (using double pointers) to set the address of the receiver if its nil. See method "Set" and "swap".

But, this doesnt seem to work. The program doesn't fail or anything, but the "EncodeThis" struct will not contain a reference to this new address. Any idea for a fix for this?

I159
  • 29,741
  • 31
  • 97
  • 132
Joachim
  • 320
  • 3
  • 12
  • Your playground is incomplete. Please fix it to compilable state. – I159 Mar 09 '17 at 10:11
  • The problem is that its thousand lines of code, and a lot of dependencies. The problem lies in the method Set, when the receiver pointer is nil. I need to allocate memory to it or re-assign the address, inside the Set-method. But I dont know how to do this. Or if its really possible. Worst case I need to create memory to them upon creation, but then having it as a pointer is useless. – Joachim Mar 09 '17 at 10:15
  • You may want to look at http://stackoverflow.com/questions/23695479/format-timestamp-in-outgoing-json-in-golang – Ravi R Mar 09 '17 at 10:22
  • I have an Idea. Please see my answer, i believe it could be helpful. – I159 Mar 09 '17 at 15:21

1 Answers1

2

Wrap your date object with a struct containing a pointer to time.Time object.

// JWDate: Numeric date value
type jWDate struct {
    date *time.Time
}

func (jwd *jWDate) Set(t *time.Time) {
    if jwd.date == nil {
        jwd.date = t
    }
}

If you need to have access to time.Time methods from jWDate struct you can embed it. With embedded type you still have ease access to an object's pointer:

// JWDate: Numeric date value
type jWDate struct {
    *time.Time // Embedded `time.Time` type pointer, not just an attribute
}

func (jwd *jWDate) Set(t *time.Time) {
    if jwd.Time == nil {
        jwd.Time = t
    }
}
I159
  • 29,741
  • 31
  • 97
  • 132
  • Thanks. But I had to re-design how I dealt with this, and it's similar to how you've done it. I extended the `jWDate`-structure to simply have `New()` method, which allocate memory (its up to the programmer to actually use this it needed) to ensure that the memory address wasn't altered by any other go-routine. – Joachim Apr 08 '17 at 21:04