Reputation: 7742
How to set default value for Encoding
as "base64"?
type FileData struct {
UID string `json:"uid"`
Size int `json:"size"`
Content string `json:content`
Encoding string `json:encoding`
User string `json:"user"`
}
I tried
Encoding string `json:encoding`= "base64" // Not working
Upvotes: 19
Views: 70306
Reputation: 341
You can set default value when you init your 'FileData'
See my example: https://play.golang.org/p/QXwDG7_mul
Page 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)
}
Upvotes: 26
Reputation: 147
If there is a need to read the struct values from environment variables, then "github.com/kelseyhightower/envconfig" library can be used and then you can declare your struct as below:
type FileData struct {
UID string `envconfig:"uid"`
Size int `envconfig:"size"`
Content string `envconfig:content`
Encoding string `envconfig:encoding default:"base64"`
User string `envconfig:"user"`
}
You can finally unmarshal JSON to your struct.
Note: I know this is not what you asked for, but this might help someone.
Upvotes: 1
Reputation: 55443
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.
Upvotes: 7
Reputation: 9116
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
Upvotes: 13