In this part of the code, ms
gets copied into an interface{}
variable:
// Trying another method (UNSUCCESSFUL)
if ret, err := json.Marshal(ms); err != nil {
The problem is that this variable does not implement the json.Marshaler
interface, since MarshalJSON
is not in the method set for myStruct
(only for *myStruct
).
The fix is to either (a) make your MarshalJSON
method take a non-pointer receiver (which will mean it gets a copy of the struct: possibly costly if it is large), or (b) marshal a pointer to the struct (as Kavu mentioned in a comment).
The reason for this behaviour is that Go doesn’t let you take a pointer to the value stored inside an interface variable, instead requiring you to make a copy of the value whenever you want to access it. While the language has syntactic sugar to convert ms.MarshalJSON()
into (&ms).MarshalJSON()
as a way to access the method with a pointer receiver, this can not be done for a value stored in an interface variable. For this reason, the method is not considered to be in its method set.