Default value golang struct using `encoding/json` ?
You can set default value when you init your 'FileData'
See my example: https://play.golang.org/p/QXwDG7_mulPage int
has default value 33
package main
import (
"encoding/json"
"fmt"
)
type Response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"`
}
func main() {
str := `{"fruits": ["apple", "peach"]}`
res := Response2{Page: 33 /*Default value*/}
json.Unmarshal([]byte(str), &res)
fmt.Println(res)
}
You can't because in Go types do not have constructors.
Instead, have either an explicit initializer function (or method on the pointer receiver) or a constructor/factory function (these are conventionally called New<TypeName>
so yours would be NewFileData
) which would return an initialized value of your type.
All-in-all, I have a feeling this looks like an XY problem. From your question, it appears you want to have a default value on one of your fields if nothing was unmarshaled.
If so, just post-process the values of this type unmarshaled from JSON and if nothing was unmarshaled to Encodning
set it to whatever default you want.
Alternatively you might consider this approach:
Have a custom type for your field.
Something like
type EncodingMethod string
should do.Have a custom JSON unmarshaling method for this type which would do whatever handling it wants.
Since your FileData
isn't too complex, you can easily make use of json.Unmarshaler
interface. Declare Encoding
as a separate type and set the default value in the unmarshal method:
type FileData struct {
UID string `json:"uid"`
Size int `json:"size"`
Content string `json:content`
Encoding Encoding `json:encoding` // declared as a custom type
User string `json:"user"`
}
type Encoding string
// implement the Unmarshaler interface on Encoding
func (e *Encoding) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
if s == "" {
*e = Encoding("base64")
} else {
*e = Encoding(s)
}
return nil
}
Now when you encode a json with empty Encoding
value, it'll be set to base64
:
var data1 = []byte(`{"uid": "UID", "size": 10, "content": "CONTENT", "encoding": "ASCII", "user": "qwe"}`)
var data2 = []byte(`{"uid": "UID", "size": 10, "content": "CONTENT", "encoding": "", "user": "qwe"}`)
func main() {
fmt.Println("Hello, playground")
f := FileData{}
if e := json.Unmarshal(data1, &f); e != nil {
fmt.Println("Error:", e)
}
fmt.Println(f, f.Encoding)
if e := json.Unmarshal(data2, &f); e != nil {
fmt.Println("Error:", e)
}
fmt.Println(f, f.Encoding)
}
Output:
{UID 10 CONTENT ASCII qwe} ASCII
{UID 10 CONTENT base64 qwe} base64
Working code: https://play.golang.org/p/y5_wBgHGJk