Doron Behar
Doron Behar

Reputation: 2878

Type conversion between two struct pointers

I have a struct that consists of a custom time.Time defined for the sake of it having a custom MarshalJSON() interface, following this answer's suggestion:

type MyTime time.Time
func (s myTime) MarshalJSON() ([]byte, error) {
    t := time.Time(s)
    return []byte(t.Format(`"20060102T150405Z"`)), nil
}

I define a MyStruct type with ThisDate and ThatDate fields of type *MyTime:

type MyStruct struct {
    ThisDate *MyTime `json:"thisdate,omitempty"`
    ThatDate *MyTime `json:"thatdate,omitempty"`
}

As far as I understand, I need to use *MyTime and not MyTime so the omitempty tag will have an effect when I'll MarshalJSON a variable of this type, following this answer's suggestion.

I use a library that has a function that returns me a struct with some fields of type *time.Time:

someVar := Lib.GetVar()

I tried to define a variable of type MyStruct like this:

myVar := &MyStruct{
    ThisDate: someVar.ThisDate
    ThatDate: someVar.ThatDate
}

Naturally, it gives me a compilation error:

cannot use someVar.ThisDate (variable of type *time.Time) as *MyTime value in struct literal ...

I tried typecasting someVar.ThisDate with */& and without these without luck. I thought the following would work:

myVar := &MyStruct{
    ThisDate: *MyTime(*someVar.ThisDate)
    ThatDate: *MyTime(*someVar.ThatDate)
}

But it gives me a different compilation error:

invalid operation: cannot indirect MyTime(*someVar.ThisDate) (value of type MyTime) ...

It seems I probably lack basic understanding of pointers and dereferences in Go. Never the less, I would like to avoid finding a specific solution for my issue which comes down to the combination of the need to make omitempty have an effect and a custom MarshalJSON.

Upvotes: 1

Views: 1997

Answers (1)

Doron Behar
Doron Behar

Reputation: 2878

The problem is the ambiguous syntax of *T(v) or whatever else you tried there. The Golang's spec gives useful examples for type conversions as this, quoting:

*Point(p)        // same as *(Point(p))
(*Point)(p)      // p is converted to *Point

Therefor, since *Point is needed, *T(v) should be used.

Upvotes: 6

Related Questions