Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: MarshalJSON isn't called for fields of a non-pointer struct #7536

gopherbot opened this issue Mar 13, 2014 · 2 comments


Copy link

by timothy.stranex:

$ go version
go version go1.2 darwin/amd64

Here is a link to a program on that demonstrates the problem.

For reference, this is the program:

package main

import "encoding/json"
import "fmt"

type DecimalE8 int64

func (d *DecimalE8) MarshalJSON() ([]byte, error) {
    return []byte(fmt.Sprintf("%.8f", float64(*d) / 1e8)), nil

type Payment struct {
    Amount DecimalE8

func main() {
    var p Payment
    p.Amount = 123456789

    s1, _ := json.Marshal(p)

    s2, _ := json.Marshal(&p)

The actual output from this program is:

The expected output is:

Basically it seems that DecimalE8.MarshalJSON isn't being used when the struct is passed
as a value to json.Marshal but it is used when it's passed as a pointer. I would expect
that DecimalE8.MarshalJSON be used in both cases.
Copy link

Comment 1:

The behavior looks correct.
If you change your MarshalJSON to the following you will get your expected behavior.
func (d DecimalE8) MarshalJSON() ([]byte, error) {
    return []byte(fmt.Sprintf("%.8f", float64(d) / 1e8)), nil

Copy link

adg commented Mar 31, 2014

Comment 2:

The language specifies that if *T implements the methods of an interface I then only a
*T (pointer) value will satisfy I, and not a T (value) value. So encoding/json can't see
that *DecimalE8 implements MarshalJSON because it only has a DecimalE8 value.
It is important to preserve this property, because a value implemented on *T might
assume that it can modify the underlying T value (which, given a value receiver, it
could not).

Status changed to WorkingAsIntended.

@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet

No branches or pull requests

3 participants