Tips for using JSON in Golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Catalogue [−]

  1. Temporarily ignores struct empty fields
  2. Temporarily add extra fields
  3. Temporary bonding of two structs
  4. A JSON cut into two structs
  5. field for temporarily renaming a struct
  6. Passing numbers with a string
  7. Tolerate string and digital cross-transfer
  8. Tolerate empty arrays as objects
  9. Support Time.time with Marshaljson
  10. Support Time.time with Registertypeencoder
  11. Use Marshaltext to support a map with non-string as key
  12. Use JSON. Rawmessage
  13. Use JSON. Number
  14. Change the naming style of a field uniformly
  15. Use a private field
  16. Ignore some fields
  17. 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. omitemptyinstead 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,})
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.