This is a creation in Article, where the information may have evolved or changed.
Catalogue [−]
- Temporarily ignores struct empty fields
- Temporarily add extra fields
- Temporary bonding of two structs
- A JSON cut into two structs
- field for temporarily renaming a struct
- Passing numbers with a string
- Tolerate string and digital cross-transfer
- Tolerate empty arrays as objects
- Support Time.time with Marshaljson
- Support Time.time with Registertypeencoder
- Use Marshaltext to support a map with non-string as key
- Use JSON. Rawmessage
- Use JSON. Number
- Change the naming style of a field uniformly
- Use a private field
- Ignore some fields
- Ignore some fields 2
Taowen is the author of Json-iterator. Serialization and deserialization need to handle the relationship between JSON and struct, and some techniques are used. The tip of using JSON in the original Golang is his experience, introducing some of the techniques that structs parse into JSON, as well as some handy handling of the Json-iterator library.
Sometimes the upstream field is a string type, but we want to use it as a number. Originally with a JSON: ", string" can be supported, if you do not know golang these tips, it will be a lot of trouble.
Reference article: http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/
Temporarily ignores struct empty fields
12345 |
type struct { email string' json: ' email ' ' string' JSON: ' Password ' //Manymore fields ...} |
If you want to temporarily ignore empty Password
fields, you can use omitempty
:
123456 |
Json. Marshal (struct { *user bool' JSON: "Password,omitempty" '} { User:user,}) |
Temporarily add extra fields
12345 |
type struct { email string' json: ' email ' ' string' JSON: ' Password ' //Manymore fields ...} |
Temporarily ignores empty Password
fields, and adds token
fields
12345678 |
Json. Marshal (struct { *user token string' JSON: ' token' bool ' JSON: ' Password,omitempty'} { user:user, Token:token,}) |
Temporary bonding of two structs
By embedding a struct:
1234567891011121314 |
type struct { URL string' json: ' url ' ' string' json: ' title ' '}type struct { Visitors int' json: ' Visitors ' ' int ' JSON: ' Page_views'} Json. Marshal (struct{ *blogpost *analytics}{post, Analytics}) |
A JSON cut into two structs
123456789 |
Json. Unmarshal ([]byte(' {' " url": "attila@attilaolah.eu", "title": "Attila ' s Blog", " Visitors ": 6, " page_views ":"), &struct { *blogpost *analytics}{&post, & Analytics}) |
field for temporarily renaming a struct
12345678910111213141516171819202122232425 |
typeCacheItemstruct{Keystring ' JSON: ' Key 'MaxAgeint ' JSON: ' Cacheage 'Value value' JSON: ' Cachevalue '}json. Marshal (struct{*cacheitem//Omit bad keysOmitmaxage Omit' JSON: ' Cacheage,omitempty 'Omitvalue Omit' JSON: ' Cachevalue,omitempty ' //Add nice keysMaxAgeint ' JSON: ' Max_age 'Value *value' JSON: ' Value '} {Cacheitem:item,//Set the int by value:Maxage:item. MaxAge,//Set the nested struct by reference, avoid making a copy:Value: &item. Value,}) |
Passing numbers with a string
123 |
type struct { int ' json: ', String'} |
This corresponding JSON is{"Field1": "100"}
If JSON is {"Field1": 100}
the error will be
Tolerate string and digital cross-transfer
If you are using Jsoniter, you can start the blur mode to support the JSON that PHP passes over.
123 |
Import "Github.com/json-iterator/go/extra"extra. Registerfuzzydecoders () |
This allows you to handle problems with strings and numbers that are not the same type. Like what
12 |
var stringjsoniter. Unmarshalfromstring (' + ', &val) |
Another example
12 |
var float32Jsoniter. Unmarshalfromstring (' 1.23', &val) |
Tolerate empty arrays as objects
Another frustrating part of PHP is that if the PHP array is empty, the serialization is []
. But when it's not empty, it's serialized out {"key":"value"}
. We need to treat it as a []
{}
deal.
If you are using Jsoniter, you can start the Blur mode to support the JSON that PHP passes over.
123 |
Import "Github.com/json-iterator/go/extra"extra. Registerfuzzydecoders () |
So that we can support the
12 |
var Map [string] Interface {}jsoniter. Unmarshalfromstring (' [] ', &val) |
Support Time.time with Marshaljson
Golang is serialized by default time.Time
in string format. If we want to express in other ways time.Time
, we need to customize the type and define it MarshalJSON
.
123456 |
type timeimplementedmarshaler time. Timefunc (obj timeimplementedmarshaler) Marshaljson () ([]byte, error) { seconds: = time. Time (obj). Unix () return []byte(StrConv. Formatint (seconds, Nil} |
Marshaljson is called when serializing
123456789 |
type struct { Field timeimplementedmarshaler}should: = require. New (t) val: = Timeimplementedmarshaler (time. Unix(123, 0)) obj: = testobject{val}bytes, err: = Jsoniter. Marshal (obj) should. Nil (Err) should. Equal (' {' Field ': 123} 'string(bytes)) |
Support Time.time with Registertypeencoder
Jsoniter can customize the JSON codec for a type that is not your definition. For example, the time.Time
epoch Int64 can be used to serialize
12345 |
Import "Github.com/json-iterator/go/extra"extra. Registertimeasint64codec (time. microsecond) OUTPUT, err: = Jsoniter. Marshal (time. Unix(1, 1002)) should. Equal ("1000001"string(Output)) |
If you want to customize, see RegisterTimeAsInt64Codec
the implementation code
Use Marshaltext to support a map with non-string as key
Although JSON is only supported as a standard string
key
map
. But Golang through the MarshalText()
interface, so that other types can also be used map
key
. For example
1234 |
F, _, _: = big. Parsefloat ("1", ten, map[*big. Float]string"2"}str, err: = Marshaltostring (val) should. Equal (' {"1": "2"} ', str) |
Which big.Float
is the realization ofMarshalText()
Use JSON. Rawmessage
If some JSON documents do not have a standard format, we can save the original information []byte
.
1234567 |
type struct { string Field2 json. Rawmessage}var data Testobjectjson.unmarshal ([]byte(' {"" field1 ":" Hello "," field2 ": [[i]} ' ), &data) should. Equal (' [+] 'string(data. FIELD2)) |
Use JSON. Number
By default, if the interface{}
corresponding number is the case, it will be of float64
type. If you enter a larger number, this representation can be detrimental to accuracy. So you can UseNumber()
enable json.Number
to represent numbers in strings.
12345 |
Decoder1: = json. Newdecoder (bytes. Newbufferstring (' 123 ')) decoder1. Usenumber ()varinterface{}decoder1. Decode (&OBJ1) should. Equal (JSON. Number ("123"), Obj1) |
Jsoniter supports this usage of the standard library. At the same time, expanding the behavior makes Unmarshal
it possible to support it UseNumber
.
1234 |
JSON: = Config{usenumber:true}. Froze ()varinterface{}json. Unmarshalfromstring ("123", &obj) should. Equal (JSON. Number ("123"), obj) |
Change the naming style of a field uniformly
Often field names in JSON are not the same as field names in Go. We can use field tag to modify it.
12345678 |
Output, err: = Jsoniter. Marshal (struct { UserName string' JSON: "user_name" ' string' JSON: "First_language" '} { UserName: "Taowen", "Chinese",}) should. Equal (' {"user_name": "Taowen", "first_language": "Chinese"} 'string(Output)) |
But a field to set, too troublesome. If you use Jsoniter, we can set the naming style uniformly.
123456789101112 |
Import "Github.com/json-iterator/go/extra"extra. Setnamingstrategy (lowercasewithunderscores) output, err: = Jsoniter. Marshal (struct { UserName string }} { UserName: " Taowen ", " Chinese ",}) should. Nil (Err) should. Equal (' {"user_name": "Taowen", "first_language": "Chinese"} 'string(Output)) |
Use a private field
The standard library for Go supports only public field. Jsoniter additional support for the private field. Need to be used SupportPrivateFields()
to turn on the switch.
123456789 |
Import "Github.com/json-iterator/go/extra"extra. Supportprivatefields ()typestruct { string}obj: = Testobject{}jsoniter. Unmarshalfromstring (' {' field1 ': ' Hello '} ', &obj) should. Equal ("Hello", Obj.field1) |
Here's what I'm adding.
Ignore some fields
There was an error in the first section of the original, and I corrected it. omitempty
instead of ignoring a field, the empty field is ignored, and it does not appear in the JSON data when the value of the field is a null value.
If you want to ignore a field, you need to use a json:"-"
format.
12345 |
type struct { email string' json: ' email ' ' string' JSON: ' Password ' //Manymore fields ...} |
If you want to temporarily ignore empty Password
fields, you can use -
:
123456 |
Json. Marshal (struct { *user bool' JSON: "-" '} { User:user,}) |
Ignore some fields 2
If you do not want to change the original struct, you can also use the following method:
12345678910111213141516 |
type struct { email string' json: ' email ' ' string' JSON: ' Password ' //Manymore fields ...} type omit *struct{}typestruct { *user ' JSON: "-" ' }json. Marshal (publicuser{ User:user,}) |