You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$ go version
go version go1.2 darwin/amd64
Here is a link to a program on play.golang.org that demonstrates the problem.
http://play.golang.org/p/HXNEgYhZgE
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)
fmt.Println(string(s1))
s2, _ := json.Marshal(&p)
fmt.Println(string(s2))
}
-------
The actual output from this program is:
{"Amount":123456789}
{"Amount":1.23456789}
The expected output is:
{"Amount":1.23456789}
{"Amount":1.23456789}
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.
The text was updated successfully, but these errors were encountered:
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
}
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).
by timothy.stranex:
The text was updated successfully, but these errors were encountered: