Consider this example:
package main
import (
"encoding/json"
"fmt"
)
type InternalStructFirst struct {
Field string `json:"field"`
}
type ExternalStruct struct {
StructA InternalStructFirst `json:"struct_a"`
StructB *InternalStructFirst `json:"struct_b"`
}
func main() {
var structVar ExternalStruct
string1 := "{\"struct_a\":{\"field\":\"a\"},\"struct_b\":{\"field\":\"b\"}}"
json.Unmarshal([]byte(string1), &structVar)
fmt.Printf("first: %+v %+v\n", structVar.StructA, structVar.StructB)
string2 := "{\"struct_a\":{\"field\":\"c\"}}"
json.Unmarshal([]byte(string2), &structVar)
fmt.Printf("second: %+v %+v\n", structVar.StructA, structVar.StructB)
var structVar2 ExternalStruct
json.Unmarshal([]byte(string2), &structVar)
fmt.Printf("third: %+v %+v\n", structVar2.StructA, structVar2
}
Which outputs:
first: {Field:a} &{Field:b}
second: {Field:c} &{Field:b}
third: {Field:} <nil>
When I do json.Unmarshal
the first time, StructB is presented in the response, and is unmarshalled correctly. But when I do it the second time, it seems like it doesn't explicitly set it to nil when the field is not presented in the response. It does set it to nil (or apparently rather does not set it to something) when doing it to a struct that does not have this field set (as seen in the third example).
How can I change my example so the second json.Unmarshal
would explicitly set the StructB
to nil when parsing a JSON string that does not have struct_b
field in it, if I have struct_b
set to not nil already?
You can't. json.Unmarshal
will not modify struct fields that are not represented in the input JSON. Either use an empty struct to start with, or set any fields to whatever value you want them to have if they're not in the JSON input before you call Unmarshal
.