MarshalJSON works for pointer struct but not for non-pointer struct

1,780 views
Skip to first unread message

Fatih Arslan

unread,
Jun 1, 2014, 2:01:08 PM6/1/14
to golang-nuts
Hi,

My problem is defined and explained here:

http://play.golang.org/p/VIUqPEqVCP

I'm confused because I've defined my methods for my inner type `State`
but it seems I need to take care of what I've pass as the outer type ?
(In my case it's the struct T). As written in the snippet, when I
change `(s *State)` to `(s State)` everything is fine. As a side
note, it seems time.MarshalJSON is also defined in terms of
non-pointer receiver.

Thanks in advance

Regards
--
Fatih Arslan

Matt Harden

unread,
Jun 1, 2014, 9:01:15 PM6/1/14
to Fatih Arslan, golang-nuts
Sorry, I forgot to reply-all.

It all comes down to addressability. json.Marshal accepts an interface{} value. When you pass a struct as an interface{}, the resulting value is not addressable. If it's not addressable, you can't take its address using the & operator, and you can't take the address of a field within it either. See this example http://play.golang.org/p/pwZOzMaM4O.

When json.Marshal is passed a pointer to a struct, then when marshaling a field, it looks to see if the pointer to the field implements the json.Marshaler interface. If it doesn't have a pointer, it can only look for a non-pointer implementation of json.Marshaler, because it doesn't have a pointer to the field.

Basically, if you don't have the address of a struct, you can't get the address of a field in that struct, and so you can't call a method on that field that requires a pointer receiver.

Does that help?

Regards,
Matt


On Sun, Jun 1, 2014 at 7:15 PM, Fatih Arslan <ftha...@gmail.com> wrote:
Hey Matt,

Thanks for the reply (seems it's only for me rather than the whole
go-nutr group). Anyway I'm curious about this detail here:

"This is because json.Marshal cannot obtain a pointer to a field when
the struct is not passed as a pointer"

Why ? Why it is obtaining it when the struct is a pointer? The rest
makes sense otherwise.

Regards

On Sun, Jun 1, 2014 at 3:49 PM, Matt Harden <matt....@gmail.com> wrote:
> This is because json.Marshal cannot obtain a pointer to a field when the
> struct is not passed as a pointer. Since you've only implemented MarshalJSON
> for a *State and not a State, json.Marshal has to fall back on its generic
> marshaling for the State field. Since your State field is just an int, why
> do you want to define MarshalJSON with a pointer receiver?
>
> This is exactly why time.MarshalJSON is also defined with a non-pointer
> receiver.
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>



--
Fatih Arslan

Fatih Arslan

unread,
Jun 1, 2014, 9:48:54 PM6/1/14
to Matt Harden, golang-nuts
That makes sense now. Thanks for the helpful answer.
--
Fatih Arslan

Jesse McNelis

unread,
Jun 1, 2014, 9:56:30 PM6/1/14
to Matt Harden, Fatih Arslan, golang-nuts
On Mon, Jun 2, 2014 at 11:00 AM, Matt Harden <matt....@gmail.com> wrote:
> Sorry, I forgot to reply-all.
>
> It all comes down to addressability. json.Marshal accepts an interface{}
> value. When you pass a struct as an interface{}, the resulting value is not
> addressable. If it's not addressable, you can't take its address using the &
> operator, and you can't take the address of a field within it either. See
> this example http://play.golang.org/p/pwZOzMaM4O.
>
> When json.Marshal is passed a pointer to a struct, then when marshaling a
> field, it looks to see if the pointer to the field implements the
> json.Marshaler interface. If it doesn't have a pointer, it can only look for
> a non-pointer implementation of json.Marshaler, because it doesn't have a
> pointer to the field.

In fact it's simpler than this.
http://golang.org/ref/spec#Method_sets




--
=====================
http://jessta.id.au
Reply all
Reply to author
Forward
0 new messages