Golang Interface{} Type Misunderstanding
When using an interface{} as a function parameter type in Go, it's important to understand how it affects the usage of json.Unmarshal. Passing a non-pointer type to an interface{} parameter can lead to unexpected results.
Scenario 1: Passing a Non-Pointer Value to Interface{}
In the given example, a Test struct is passed directly to the test function, which expects an interface{} parameter:
test(Test{})
The output shows that the struct has been converted into a map[string]interface{} by json.Unmarshal:
main.Test *interface {} map[string]interface {}
This is because interface{} wraps a (value; type) pair, and the passed value is non-pointer, so the json package creates a new value to unmarshal into. Since the default for JSON objects is map[string]interface{}, this is what's created.
Scenario 2: Passing a Pointer to Interface{}
Passing a pointer to the Test struct to the test function, however, produces the expected result:
test(&Test{})
*main.Test *interface {} *main.Test &{bar}
This is because the pointer to the struct is passed to json.Unmarshal, allowing it to unmarshal directly into the pointed Test value.
Explanation: Pointers and Interfaces
When a package needs to modify a value stored in an interface{}, it needs to receive a pointer to it. In the case of json.Unmarshal, it expects a pointer to unmarshal into. When you have an interface{} value that already wraps a pointer, simply pass it along without taking its address again.
Best Practice
Avoid using pointers to interfaces. Instead, put pointers into the interfaces by wrapping them in the interface value. When you need to pass an interface{} holding a pointer, just pass it along directly.
The above is the detailed content of Why Does `json.Unmarshal` Behave Differently with Pointer and Non-Pointer Values Passed to an `interface{}` Parameter in Go?. For more information, please follow other related articles on the PHP Chinese website!