Movatterモバイル変換


[0]ホーム

URL:


json

packagemodule
v0.0.0-...-4849db3Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2025 License:BSD-3-ClauseImports:25Imported by:368

Details

Repository

github.com/go-json-experiment/json

Links

README

JSON Serialization (v2)

GoDevBuild Status

This module hosts an experimental implementation of v2encoding/json.The API is unstable and breaking changes will regularly be made.Do not depend on this in publicly available modules.

Any commits that make breaking API or behavior changes will be markedwith the string "WARNING: " near the top of the commit message.It is your responsibility to inspect the list of commit changeswhen upgrading the module. Not all breaking changes will lead to build failures.

Aproposal to include this module in Go asencoding/json/v2 andencoding/json/jsontext has been started on the Go Github project on 2025-01-30. Please provide your feedback there.At present, this module is available within the Go standard library as a Go experiment.See"A new experimental Go API for JSON" for more details.

Goals and objectives

  • Mostly backwards compatible: If possible, v2 should aim to bemostlycompatible with v1 in terms of both API and default behavior to ease migration.For example, theMarshal andUnmarshal functions are the most widely useddeclarations in the v1 package. It seems sensible for equivalent functionalityin v2 to be named the same and have a mostly compatible signature.Behaviorally, we should aim for 95% to 99% backwards compatibility.We do not aim for 100% compatibility since we want the freedom to breakcertain behaviors that are now considered to have been a mistake.Options exist that can bring the v2 implementation to 100% compatibility,but it will not be the default.

  • More flexible: There is along list of feature requests.We should aim to provide the most flexible features that addresses most usages.We do not want to over fit the v2 API to handle every possible use case.Ideally, the features provided should be orthogonal in nature such thatany combination of features results in as few surprising edge cases as possible.

  • More performant: JSON serialization is widely used and any bit of extraperformance gains will be greatly appreciated. Some rarely used behaviors of v1may be dropped in favor of better performance. For example,despiteEncoder andDecoder operating on anio.Writer andio.Reader,they do not operate in a truly streaming manner,leading to a loss in performance. The v2 implementation should aim to be trulystreaming by default (see#33714).

  • Easy to use (hard to misuse): The v2 API should aim to makethe common case easy and the less common case at least possible.The API should avoid behavior that goes contrary to user expectation,which may result in subtle bugs (see#36225).

  • v1 and v2 maintainability: Since the v1 implementation must stay forever,it would be beneficial if v1 could be implemented under the hood with v2,allowing for less maintenance burden in the future. This probably implies thatbehavioral changes in v2 relative to v1 need to be exposed as options.

  • Avoid unsafe: Standard library packages generally avoid the use ofpackageunsafe even if it could provide a performance boost.We aim to preserve this property.

Expectations

While this module aims to possibly be the v2 implementation ofencoding/json,there is no guarantee that this outcome will occur. As with any major changeto the Go standard library, this will eventually go through theGo proposal process.At the present moment, this is still in the design and experimentation phaseand is not ready for a formal proposal.

There are several possible outcomes from this experiment:

  1. We determine that a v2encoding/json would not provide sufficient benefitover the existing v1encoding/json package. Thus, we abandon this effort.
  2. We propose a v2encoding/json design, but it is rejected in favor of someother design that is considered superior.
  3. We propose a v2encoding/json design, but rather than adding an entirelynew v2encoding/json package, we decide to merge its functionality intothe existing v1encoding/json package.
  4. We propose a v2encoding/json design and it is accepted, resulting inits addition to the standard library.
  5. Some other unforeseen outcome (among the infinite number of possibilities).

Development

This module is primarily developed by@dsnet,@mvdan, and@johanbrandhorstwith feedback provided by@rogpeppe,@ChrisHines, and@rsc.

Discussion about semantics occur semi-regularly, where arecord of past meetings can be found here.

Design overview

This package aims to provide a clean separation between syntax and semantics.Syntax deals with the structural representation of JSON (as specified inRFC 4627,RFC 7159,RFC 7493,RFC 8259, andRFC 8785).Semantics deals with the meaning of syntactic data as usable application data.

TheEncoder andDecoder types are streaming tokenizers concerned with thepacking or parsing of JSON data. They operate onToken andValue typeswhich represent the common data structures that are representable in JSON.Encoder andDecoder do not aim to provide any interpretation of the data.

Functions likeMarshal,MarshalWrite,MarshalEncode,Unmarshal,UnmarshalRead, andUnmarshalDecode provide semantic meaning by correlatingany arbitrary Go type with some JSON representation of that type (as stored indata types like[]byte,io.Writer,io.Reader,Encoder, orDecoder).

API overview

This diagram provides a high-level overview of the v2json andjsontext packages.Purple blocks represent types, while blue blocks represent functions or methods.The arrows and their direction represent the approximate flow of data.The bottom half of the diagram contains functionality that is only concernedwith syntax (implemented by thejsontext package),while the upper half contains functionality that assignssemantic meaning to syntactic data handled by the bottom half(as implemented by the v2json package).

In contrast to v1encoding/json, options are represented as separate typesrather than being setter methods on theEncoder orDecoder types.Some options affects JSON serialization at the syntactic layer,while others affect it at the semantic layer.Some options only affect JSON when decoding,while others affect JSON while encoding.

Behavior changes

The v2json package changes the default behavior ofMarshal andUnmarshalrelative to the v1json package to be more sensible.Some of these behavior changes have options and workarounds to opt intobehavior similar to what v1 provided.

This table shows an overview of the changes:

v1v2Details
JSON object members are unmarshaled into a Go struct using acase-insensitive name match.JSON object members are unmarshaled into a Go struct using acase-sensitive name match.CaseSensitivity
When marshaling a Go struct, a struct field marked asomitempty is omitted ifthe field value is an empty Go value, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string.When marshaling a Go struct, a struct field marked asomitempty is omitted ifthe field value would encode as an empty JSON value, which is defined as a JSON null, or an empty JSON string, object, or array.OmitEmptyOption
Thestring optiondoes affect Go strings and bools.Thestring optiondoes not affect Go strings or bools.StringOption
Thestring optiondoes not recursively affect sub-values of the Go field value.Thestring optiondoes recursively affect sub-values of the Go field value.StringOption
Thestring optionsometimes accepts a JSON null escaped within a JSON string.Thestring optionnever accepts a JSON null escaped within a JSON string.StringOption
A nil Go slice is marshaled as aJSON null.A nil Go slice is marshaled as anempty JSON array.NilSlicesAndMaps
A nil Go map is marshaled as aJSON null.A nil Go map is marshaled as anempty JSON object.NilSlicesAndMaps
A Go array may be unmarshaled from aJSON array of any length.A Go array must be unmarshaled from aJSON array of the same length.Arrays
A Go byte array is represented as aJSON array of JSON numbers.A Go byte array is represented as aBase64-encoded JSON string.ByteArrays
MarshalJSON andUnmarshalJSON methods declared on a pointer receiver areinconsistently called.MarshalJSON andUnmarshalJSON methods declared on a pointer receiver areconsistently called.PointerReceiver
A Go map is marshaled in adeterministic order.A Go map is marshaled in anon-deterministic order.MapDeterminism
JSON strings are encodedwith HTML-specific characters being escaped.JSON strings are encodedwithout any characters being escaped (unless necessary).EscapeHTML
When marshaling, invalid UTF-8 within a Go stringare silently replaced.When marshaling, invalid UTF-8 within a Go stringresults in an error.InvalidUTF8
When unmarshaling, invalid UTF-8 within a JSON stringare silently replaced.When unmarshaling, invalid UTF-8 within a JSON stringresults in an error.InvalidUTF8
When marshaling,an error does not occur if the output JSON value contains objects with duplicate names.When marshaling,an error does occur if the output JSON value contains objects with duplicate names.DuplicateNames
When unmarshaling,an error does not occur if the input JSON value contains objects with duplicate names.When unmarshaling,an error does occur if the input JSON value contains objects with duplicate names.DuplicateNames
Unmarshaling a JSON null into a non-empty Go valueinconsistently clears the value or does nothing.Unmarshaling a JSON null into a non-empty Go valuealways clears the value.MergeNull
Unmarshaling a JSON value into a non-empty Go valuefollows inconsistent and bizarre behavior.Unmarshaling a JSON value into a non-empty Go valuealways merges if the input is an object, and otherwise replaces.MergeComposite
Atime.Duration is represented as aJSON number containing the decimal number of nanoseconds.Atime.Duration has no default representation in v2 (see#71631) and results in an error.
A Go struct with only unexported fieldscan be serialized.A Go struct with only unexported fieldscannot be serialized.EmptyStructs

Seediff_test.go for details about every change.

Performance

One of the goals of the v2 module is to be more performant than v1,but not at the expense of correctness.In general, v2 is at performance parity with v1 for marshaling,but dramatically faster for unmarshaling.

Seehttps://github.com/go-json-experiment/jsonbench for benchmarkscomparing v2 with v1 and a number of other popular JSON implementations.

Documentation

Overview

Package json implements semantic processing of JSON as specified inRFC 8259.JSON is a simple data interchange format that can representprimitive data types such as booleans, strings, and numbers,in addition to structured data types such as objects and arrays.

Marshal andUnmarshal encode and decode Go valuesto/from JSON text contained within a []byte.MarshalWrite andUnmarshalRead operate on JSON textby writing to or reading from anio.Writer orio.Reader.MarshalEncode andUnmarshalDecode operate on JSON textby encoding to or decoding from ajsontext.Encoder orjsontext.Decoder.Options may be passed to each of the marshal or unmarshal functionsto configure the semantic behavior of marshaling and unmarshaling(i.e., alter how JSON data is understood as Go data and vice versa).jsontext.Options may also be passed to the marshal or unmarshal functionsto configure the syntactic behavior of encoding or decoding.

The data types of JSON are mapped to/from the data types of Go based onthe closest logical equivalent between the two type systems. For example,a JSON boolean corresponds with a Go bool,a JSON string corresponds with a Go string,a JSON number corresponds with a Go int, uint or float,a JSON array corresponds with a Go slice or array, anda JSON object corresponds with a Go struct or map.See the documentation onMarshal andUnmarshal for a comprehensive listof how the JSON and Go type systems correspond.

Arbitrary Go types can customize their JSON representation by implementingMarshaler,MarshalerTo,Unmarshaler, orUnmarshalerFrom.This provides authors of Go types with control over how their types areserialized as JSON. Alternatively, users can implement functions that matchMarshalFunc,MarshalToFunc,UnmarshalFunc, orUnmarshalFromFuncto specify the JSON representation for arbitrary types.This provides callers of JSON functionality with control overhow any arbitrary type is serialized as JSON.

JSON Representation of Go structs

A Go struct is naturally represented as a JSON object,where each Go struct field corresponds with a JSON object member.When marshaling, all Go struct fields are recursively encoded in depth-firstorder as JSON object members except those that are ignored or omitted.When unmarshaling, JSON object members are recursively decodedinto the corresponding Go struct fields.Object members that do not match any struct fields,also known as “unknown members”, are ignored by default or rejectedifRejectUnknownMembers is specified.

The representation of each struct field can be customized in the"json" struct field tag, where the tag is a comma separated list of options.As a special case, if the entire tag is `json:"-"`,then the field is ignored with regard to its JSON representation.Some options also have equivalent behavior controlled by a caller-specifiedOptions.Field-specified options take precedence over caller-specified options.

The first option is the JSON object name override for the Go struct field.If the name is not specified, then the Go struct field nameis used as the JSON object name. JSON names containing commas or quotes,or names identical to "" or "-", can be specified usinga single-quoted string literal, where the syntax is identical tothe Go grammar for a double-quoted string literal,but instead uses single quotes as the delimiters.By default, unmarshaling uses case-sensitive matching to identifythe Go struct field associated with a JSON object name.

After the name, the following tag options are supported:

  • omitzero: When marshaling, the "omitzero" option specifies thatthe struct field should be omitted if the field value is zeroas determined by the "IsZero() bool" method if present,otherwise based on whether the field is the zero Go value.This option has no effect when unmarshaling.

  • omitempty: When marshaling, the "omitempty" option specifies thatthe struct field should be omitted if the field value would have beenencoded as a JSON null, empty string, empty object, or empty array.This option has no effect when unmarshaling.

  • string: The "string" option specifies thatStringifyNumbersbe set when marshaling or unmarshaling a struct field value.This causes numeric types to be encoded as a JSON numberwithin a JSON string, and to be decoded from a JSON stringcontaining the JSON number without any surrounding whitespace.This extra level of encoding is often necessary sincemany JSON parsers cannot precisely represent 64-bit integers.

  • case: When unmarshaling, the "case" option specifies howJSON object names are matched with the JSON name for Go struct fields.The option is a key-value pair specified as "case:value" wherethe value must either be 'ignore' or 'strict'.The 'ignore' value specifies that matching is case-insensitivewhere dashes and underscores are also ignored. If multiple fields match,the first declared field in breadth-first order takes precedence.The 'strict' value specifies that matching is case-sensitive.This takes precedence over theMatchCaseInsensitiveNames option.

  • inline: The "inline" option specifies thatthe JSON representable content of this field type is to be promotedas if they were specified in the parent struct.It is the JSON equivalent of Go struct embedding.A Go embedded field is implicitly inlined unless an explicit JSON nameis specified. The inlined field must be a Go struct(that does not implement any JSON methods),jsontext.Value,map[~string]T, or an unnamed pointer to such types. When marshaling,inlined fields from a pointer type are omitted if it is nil.Inlined fields of typejsontext.Value and map[~string]T are called“inlined fallbacks” as they can represent all possibleJSON object members not directly handled by the parent struct.Only one inlined fallback field may be specified in a struct,while many non-fallback fields may be specified. This optionmust not be specified with any other option (including the JSON name).

  • unknown: The "unknown" option is a specialized variantof the inlined fallback to indicate that this Go struct fieldcontains any number of unknown JSON object members. The field type mustbe ajsontext.Value, map[~string]T, or an unnamed pointer to such types.IfDiscardUnknownMembers is specified when marshaling,the contents of this field are ignored.IfRejectUnknownMembers is specified when unmarshaling,any unknown object members are rejected regardless of whetheran inlined fallback with the "unknown" option exists. This optionmust not be specified with any other option (including the JSON name).

  • format: The "format" option specifies a format flagused to specialize the formatting of the field value.The option is a key-value pair specified as "format:value" wherethe value must be either a literal consisting of letters and numbers(e.g., "format:RFC3339") or a single-quoted string literal(e.g., "format:'2006-01-02'"). The interpretation of the format flagis determined by the struct field type.

The "omitzero" and "omitempty" options are mostly semantically identical.The former is defined in terms of the Go type system,while the latter in terms of the JSON type system.Consequently they behave differently in some circumstances.For example, only a nil slice or map is omitted under "omitzero", whilean empty slice or map is omitted under "omitempty" regardless of nilness.The "omitzero" option is useful for types with a well-defined zero value(e.g.,net/netip.Addr) or have an IsZero method (e.g.,time.Time.IsZero).

Every Go struct corresponds to a list of JSON representable fieldswhich is constructed by performing a breadth-first search overall struct fields (excluding unexported or ignored fields),where the search recursively descends into inlined structs.The set of non-inlined fields in a struct must have unique JSON names.If multiple fields all have the same JSON name, then the oneat shallowest depth takes precedence and the other fields at deeper depthsare excluded from the list of JSON representable fields.If multiple fields at the shallowest depth have the same JSON name,but exactly one is explicitly tagged with a JSON name,then that field takes precedence and all others are excluded from the list.This is analogous to Go visibility rules for struct field selectionwith embedded struct types.

Marshaling or unmarshaling a non-empty structwithout any JSON representable fields results in aSemanticError.Unexported fields must not have any `json` tags except for `json:"-"`.

Security Considerations

JSON is frequently used as a data interchange format to communicatebetween different systems, possibly implemented in different languages.For interoperability and security reasons, it is important thatall implementations agree upon the semantic meaning of the data.

For example, suppose we have two micro-services.The first service is responsible for authenticating a JSON request,while the second service is responsible for executing the request(having assumed that the prior service authenticated the request).If an attacker were able to maliciously craft a JSON request such thatboth services believe that the same request is from different users,it could bypass the authenticator with valid credentials for one user,but maliciously perform an action on behalf of a different user.

According toRFC 8259, there unfortunately exist many JSON textsthat are syntactically valid but semantically ambiguous.For example, the standard does not define how to interpret duplicatenames within an object.

The v1encoding/json andencoding/json/v2 packagesinterpret some inputs in different ways. In particular:

  • The standard specifies that JSON must be encoded using UTF-8.By default, v1 replaces invalid bytes of UTF-8 in JSON stringswith the Unicode replacement character,while v2 rejects inputs with invalid UTF-8.To change the default, specify thejsontext.AllowInvalidUTF8 option.The replacement of invalid UTF-8 is a form of data corruptionthat alters the precise meaning of strings.

  • The standard does not specify a particular behavior whenduplicate names are encountered within a JSON object,which means that different implementations may behave differently.By default, v1 allows for the presence of duplicate names,while v2 rejects duplicate names.To change the default, specify thejsontext.AllowDuplicateNames option.If allowed, object members are processed in the order they are observed,meaning that later values will replace or be merged into prior values,depending on the Go value type.

  • The standard defines a JSON object as an unordered collection of name/value pairs.While ordering can be observed through the underlyingjsontext API,both v1 and v2 generally avoid exposing the ordering.No application should semantically depend on the order of object members.Allowing duplicate names is a vector through which ordering of memberscan accidentally be observed and depended upon.

  • The standard suggests that JSON object names are typically comparedbased on equality of the sequence of Unicode code points,which implies that comparing names is often case-sensitive.When unmarshaling a JSON object into a Go struct,by default, v1 uses a (loose) case-insensitive match on the name,while v2 uses a (strict) case-sensitive match on the name.To change the default, specify theMatchCaseInsensitiveNames option.The use of case-insensitive matching provides another vector throughwhich duplicate names can occur. Allowing case-insensitive matchingmeans that v1 or v2 might interpret JSON objects differently from mostother JSON implementations (which typically use a case-sensitive match).

  • The standard does not specify a particular behavior whenan unknown name in a JSON object is encountered.When unmarshaling a JSON object into a Go struct, by defaultboth v1 and v2 ignore unknown names and their corresponding values.To change the default, specify theRejectUnknownMembers option.

  • The standard suggests that implementations may use a float64to represent a JSON number. Consequently, large JSON integersmay lose precision when stored as a floating-point type.Both v1 and v2 correctly preserve precision when marshaling andunmarshaling a concrete integer type. However, even if v1 and v2preserve precision for concrete types, other JSON implementationsmay not be able to preserve precision for outputs produced by v1 or v2.The `string` tag option can be used to specify that an integer typeis to be quoted within a JSON string to avoid loss of precision.Furthermore, v1 and v2 may still lose precision when unmarshalinginto an any interface value, where unmarshal uses a float64by default to represent a JSON number.To change the default, specify theWithUnmarshalers optionwith a custom unmarshaler that pre-populates the interface valuewith a concrete Go type that can preserve precision.

RFC 8785 specifies a canonical form for any JSON text,which explicitly defines specific behaviors thatRFC 8259 leaves undefined.In theory, if a text can successfullyjsontext.Value.Canonicalizewithout changing the semantic meaning of the data, then it provides agreater degree of confidence that the data is more secure and interoperable.

The v2 API generally chooses more secure defaults than v1,but care should still be taken with large integers or unknown members.

Example (CaseSensitivity)

Unmarshal matches JSON object names with Go struct fields usinga case-sensitive match, but can be configured to use a case-insensitivematch with the "case:ignore" option. This permits unmarshaling from inputsthat use naming conventions such as camelCase, snake_case, or kebab-case.

package mainimport ("fmt""log""github.com/go-json-experiment/json")func main() {// JSON input using various naming conventions.const input = `[{"firstname": true},{"firstName": true},{"FirstName": true},{"FIRSTNAME": true},{"first_name": true},{"FIRST_NAME": true},{"first-name": true},{"FIRST-NAME": true},{"unknown": true}]`// Without "case:ignore", Unmarshal looks for an exact match.var caseStrict []struct {X bool `json:"firstName"`}if err := json.Unmarshal([]byte(input), &caseStrict); err != nil {log.Fatal(err)}fmt.Println(caseStrict) // exactly 1 match found// With "case:ignore", Unmarshal looks first for an exact match,// then for a case-insensitive match if none found.var caseIgnore []struct {X bool `json:"firstName,case:ignore"`}if err := json.Unmarshal([]byte(input), &caseIgnore); err != nil {log.Fatal(err)}fmt.Println(caseIgnore) // 8 matches found}
Output:[{false} {true} {false} {false} {false} {false} {false} {false} {false}][{true} {true} {true} {true} {true} {true} {true} {true} {false}]

Example (FieldNames)

By default, JSON object names for Go struct fields are derived fromthe Go field name, but may be specified in the `json` tag.Due to JSON's heritage in JavaScript, the most common naming conventionused for JSON object names is camelCase.

package mainimport ("fmt""log""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {var value struct {// This field is explicitly ignored with the special "-" name.Ignored any `json:"-"`// No JSON name is not provided, so the Go field name is used.GoName any// A JSON name is provided without any special characters.JSONName any `json:"jsonName"`// No JSON name is not provided, so the Go field name is used.Option any `json:",case:ignore"`// An empty JSON name specified using an single-quoted string literal.Empty any `json:"''"`// A dash JSON name specified using an single-quoted string literal.Dash any `json:"'-'"`// A comma JSON name specified using an single-quoted string literal.Comma any `json:"','"`// JSON name with quotes specified using a single-quoted string literal.Quote any `json:"'\"\\''"`// An unexported field is always ignored.unexported any}b, err := json.Marshal(value)if err != nil {log.Fatal(err)}(*jsontext.Value)(&b).Indent() // indent for readabilityfmt.Println(string(b))}
Output:{"GoName": null,"jsonName": null,"Option": null,"": null,"-": null,",": null,"\"'": null}

Example (FormatFlags)

The "format" tag option can be used to alter the formatting of certain types.

package mainimport ("fmt""log""math""time""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {value := struct {BytesBase64     []byte         `json:",format:base64"`BytesHex        [8]byte        `json:",format:hex"`BytesArray      []byte         `json:",format:array"`FloatNonFinite  float64        `json:",format:nonfinite"`MapEmitNull     map[string]any `json:",format:emitnull"`SliceEmitNull   []any          `json:",format:emitnull"`TimeDateOnly    time.Time      `json:",format:'2006-01-02'"`TimeUnixSec     time.Time      `json:",format:unix"`DurationSecs    time.Duration  `json:",format:sec"`DurationNanos   time.Duration  `json:",format:nano"`DurationISO8601 time.Duration  `json:",format:iso8601"`}{BytesBase64:     []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},BytesHex:        [8]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},BytesArray:      []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},FloatNonFinite:  math.NaN(),MapEmitNull:     nil,SliceEmitNull:   nil,TimeDateOnly:    time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),TimeUnixSec:     time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),DurationSecs:    12*time.Hour + 34*time.Minute + 56*time.Second + 7*time.Millisecond + 8*time.Microsecond + 9*time.Nanosecond,DurationNanos:   12*time.Hour + 34*time.Minute + 56*time.Second + 7*time.Millisecond + 8*time.Microsecond + 9*time.Nanosecond,DurationISO8601: 12*time.Hour + 34*time.Minute + 56*time.Second + 7*time.Millisecond + 8*time.Microsecond + 9*time.Nanosecond,}b, err := json.Marshal(&value)if err != nil {log.Fatal(err)}(*jsontext.Value)(&b).Indent() // indent for readabilityfmt.Println(string(b))}
Output:{"BytesBase64": "ASNFZ4mrze8=","BytesHex": "0123456789abcdef","BytesArray": [1,35,69,103,137,171,205,239],"FloatNonFinite": "NaN","MapEmitNull": null,"SliceEmitNull": null,"TimeDateOnly": "2000-01-01","TimeUnixSec": 946684800,"DurationSecs": 45296.007008009,"DurationNanos": 45296007008009,"DurationISO8601": "PT12H34M56.007008009S"}

Example (InlinedFields)

JSON objects can be inlined within a parent object similar tohow Go structs can be embedded within a parent struct.The inlining rules are similar to those of Go embedding,but operates upon the JSON namespace.

package mainimport ("fmt""log""time""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {// Base is embedded within Container.type Base struct {// ID is promoted into the JSON object for Container.ID string// Type is ignored due to presence of Container.Type.Type string// Time cancels out with Container.Inlined.Time.Time time.Time}// Other is embedded within Container.type Other struct{ Cost float64 }// Container embeds Base and Other.type Container struct {// Base is an embedded struct and is implicitly JSON inlined.Base// Type takes precedence over Base.Type.Type int// Inlined is a named Go field, but is explicitly JSON inlined.Inlined struct {// User is promoted into the JSON object for Container.User string// Time cancels out with Base.Time.Time string} `json:",inline"`// ID does not conflict with Base.ID since the JSON name is different.ID string `json:"uuid"`// Other is not JSON inlined since it has an explicit JSON name.Other `json:"other"`}// Format an empty Container to show what fields are JSON serializable.var input Containerb, err := json.Marshal(&input)if err != nil {log.Fatal(err)}(*jsontext.Value)(&b).Indent() // indent for readabilityfmt.Println(string(b))}
Output:{"ID": "","Type": 0,"User": "","uuid": "","other": {"Cost": 0}}

Example (OmitFields)

Go struct fields can be omitted from the output depending on eitherthe input Go value or the output JSON encoding of the value.The "omitzero" option omits a field if it is the zero Go value orimplements a "IsZero() bool" method that reports true.The "omitempty" option omits a field if it encodes as an empty JSON value,which we define as a JSON null or empty JSON string, object, or array.In many cases, the behavior of "omitzero" and "omitempty" are equivalent.If both provide the desired effect, then using "omitzero" is preferred.

package mainimport ("fmt""log""net/netip""time""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {type MyStruct struct {Foo string `json:",omitzero"`Bar []int  `json:",omitempty"`// Both "omitzero" and "omitempty" can be specified together,// in which case the field is omitted if either would take effect.// This omits the Baz field either if it is a nil pointer or// if it would have encoded as an empty JSON object.Baz *MyStruct `json:",omitzero,omitempty"`}// Demonstrate behavior of "omitzero".b, err := json.Marshal(struct {Bool         bool        `json:",omitzero"`Int          int         `json:",omitzero"`String       string      `json:",omitzero"`Time         time.Time   `json:",omitzero"`Addr         netip.Addr  `json:",omitzero"`Struct       MyStruct    `json:",omitzero"`SliceNil     []int       `json:",omitzero"`Slice        []int       `json:",omitzero"`MapNil       map[int]int `json:",omitzero"`Map          map[int]int `json:",omitzero"`PointerNil   *string     `json:",omitzero"`Pointer      *string     `json:",omitzero"`InterfaceNil any         `json:",omitzero"`Interface    any         `json:",omitzero"`}{// Bool is omitted since false is the zero value for a Go bool.Bool: false,// Int is omitted since 0 is the zero value for a Go int.Int: 0,// String is omitted since "" is the zero value for a Go string.String: "",// Time is omitted since time.Time.IsZero reports true.Time: time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),// Addr is omitted since netip.Addr{} is the zero value for a Go struct.Addr: netip.Addr{},// Struct is NOT omitted since it is not the zero value for a Go struct.Struct: MyStruct{Bar: []int{}, Baz: new(MyStruct)},// SliceNil is omitted since nil is the zero value for a Go slice.SliceNil: nil,// Slice is NOT omitted since []int{} is not the zero value for a Go slice.Slice: []int{},// MapNil is omitted since nil is the zero value for a Go map.MapNil: nil,// Map is NOT omitted since map[int]int{} is not the zero value for a Go map.Map: map[int]int{},// PointerNil is omitted since nil is the zero value for a Go pointer.PointerNil: nil,// Pointer is NOT omitted since new(string) is not the zero value for a Go pointer.Pointer: new(string),// InterfaceNil is omitted since nil is the zero value for a Go interface.InterfaceNil: nil,// Interface is NOT omitted since (*string)(nil) is not the zero value for a Go interface.Interface: (*string)(nil),})if err != nil {log.Fatal(err)}(*jsontext.Value)(&b).Indent()      // indent for readabilityfmt.Println("OmitZero:", string(b)) // outputs "Struct", "Slice", "Map", "Pointer", and "Interface"// Demonstrate behavior of "omitempty".b, err = json.Marshal(struct {Bool         bool        `json:",omitempty"`Int          int         `json:",omitempty"`String       string      `json:",omitempty"`Time         time.Time   `json:",omitempty"`Addr         netip.Addr  `json:",omitempty"`Struct       MyStruct    `json:",omitempty"`Slice        []int       `json:",omitempty"`Map          map[int]int `json:",omitempty"`PointerNil   *string     `json:",omitempty"`Pointer      *string     `json:",omitempty"`InterfaceNil any         `json:",omitempty"`Interface    any         `json:",omitempty"`}{// Bool is NOT omitted since false is not an empty JSON value.Bool: false,// Int is NOT omitted since 0 is not a empty JSON value.Int: 0,// String is omitted since "" is an empty JSON string.String: "",// Time is NOT omitted since this encodes as a non-empty JSON string.Time: time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),// Addr is omitted since this encodes as an empty JSON string.Addr: netip.Addr{},// Struct is omitted since {} is an empty JSON object.Struct: MyStruct{Bar: []int{}, Baz: new(MyStruct)},// Slice is omitted since [] is an empty JSON array.Slice: []int{},// Map is omitted since {} is an empty JSON object.Map: map[int]int{},// PointerNil is omitted since null is an empty JSON value.PointerNil: nil,// Pointer is omitted since "" is an empty JSON string.Pointer: new(string),// InterfaceNil is omitted since null is an empty JSON value.InterfaceNil: nil,// Interface is omitted since null is an empty JSON value.Interface: (*string)(nil),})if err != nil {log.Fatal(err)}(*jsontext.Value)(&b).Indent()       // indent for readabilityfmt.Println("OmitEmpty:", string(b)) // outputs "Bool", "Int", and "Time"}
Output:OmitZero: {"Struct": {},"Slice": [],"Map": {},"Pointer": "","Interface": null}OmitEmpty: {"Bool": false,"Int": 0,"Time": "0001-01-01T00:00:00Z"}

Example (OrderedObject)

The exact order of JSON object can be preserved through the use of aspecialized type that implementsMarshalerTo andUnmarshalerFrom.

//go:build !goexperiment.jsonv2 || !go1.25package mainimport ("fmt""log""reflect""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")// OrderedObject is an ordered sequence of name/value members in a JSON object.//// RFC 8259 defines an object as an "unordered collection".// JSON implementations need not make "ordering of object members visible"// to applications nor will they agree on the semantic meaning of an object if// "the names within an object are not unique". For maximum compatibility,// applications should avoid relying on ordering or duplicity of object names.type OrderedObject[V any] []ObjectMember[V]// ObjectMember is a JSON object member.type ObjectMember[V any] struct {Name  stringValue V}// MarshalJSONTo encodes obj as a JSON object into enc.func (obj *OrderedObject[V]) MarshalJSONTo(enc *jsontext.Encoder) error {if err := enc.WriteToken(jsontext.BeginObject); err != nil {return err}for i := range *obj {member := &(*obj)[i]if err := json.MarshalEncode(enc, &member.Name); err != nil {return err}if err := json.MarshalEncode(enc, &member.Value); err != nil {return err}}if err := enc.WriteToken(jsontext.EndObject); err != nil {return err}return nil}// UnmarshalJSONFrom decodes a JSON object from dec into obj.func (obj *OrderedObject[V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error {if k := dec.PeekKind(); k != '{' {// The [json] package automatically populates relevant fields// in a [json.SemanticError] to provide additional context.return &json.SemanticError{JSONKind: k}}if _, err := dec.ReadToken(); err != nil {return err}for dec.PeekKind() != '}' {*obj = append(*obj, ObjectMember[V]{})member := &(*obj)[len(*obj)-1]if err := json.UnmarshalDecode(dec, &member.Name); err != nil {return err}if err := json.UnmarshalDecode(dec, &member.Value); err != nil {return err}}if _, err := dec.ReadToken(); err != nil {return err}return nil}// The exact order of JSON object can be preserved through the use of a// specialized type that implements [MarshalerTo] and [UnmarshalerFrom].func main() {// Round-trip marshal and unmarshal an ordered object.// We expect the order and duplicity of JSON object members to be preserved.// Specify jsontext.AllowDuplicateNames since this object contains "fizz" twice.want := OrderedObject[string]{{"fizz", "buzz"},{"hello", "world"},{"fizz", "wuzz"},}b, err := json.Marshal(&want, jsontext.AllowDuplicateNames(true))if err != nil {log.Fatal(err)}var got OrderedObject[string]err = json.Unmarshal(b, &got, jsontext.AllowDuplicateNames(true))if err != nil {log.Fatal(err)}// Sanity check.if !reflect.DeepEqual(got, want) {log.Fatalf("roundtrip mismatch: got %v, want %v", got, want)}// Print the serialized JSON object.(*jsontext.Value)(&b).Indent() // indent for readabilityfmt.Println(string(b))}
Output:{"fizz": "buzz","hello": "world","fizz": "wuzz"}

Example (ProtoJSON)

Some Go types have a custom JSON representation where the implementationis delegated to some external package. Consequently, the "json" packagewill not know how to use that external implementation.For example, thegoogle.golang.org/protobuf/encoding/protojson packageimplements JSON for allgoogle.golang.org/protobuf/proto.Message types.WithMarshalers andWithUnmarshalers can be usedto configure "json" and "protojson" to cooperate together.

package mainimport ("log""github.com/go-json-experiment/json")func main() {// Let protoMessage be "google.golang.org/protobuf/proto".Message.type protoMessage interface{ ProtoReflect() }// Let foopbMyMessage be a concrete implementation of proto.Message.type foopbMyMessage struct{ protoMessage }// Let protojson be an import of "google.golang.org/protobuf/encoding/protojson".var protojson struct {Marshal   func(protoMessage) ([]byte, error)Unmarshal func([]byte, protoMessage) error}// This value mixes both non-proto.Message types and proto.Message types.// It should use the "json" package to handle non-proto.Message types and// should use the "protojson" package to handle proto.Message types.var value struct {// GoStruct does not implement proto.Message and// should use the default behavior of the "json" package.GoStruct struct {Name stringAge  int}// ProtoMessage implements proto.Message and// should be handled using protojson.Marshal.ProtoMessage *foopbMyMessage}// Marshal using protojson.Marshal for proto.Message types.b, err := json.Marshal(&value,// Use protojson.Marshal as a type-specific marshaler.json.WithMarshalers(json.MarshalFunc(protojson.Marshal)))if err != nil {log.Fatal(err)}// Unmarshal using protojson.Unmarshal for proto.Message types.err = json.Unmarshal(b, &value,// Use protojson.Unmarshal as a type-specific unmarshaler.json.WithUnmarshalers(json.UnmarshalFunc(protojson.Unmarshal)))if err != nil {log.Fatal(err)}}

Example (ServeHTTP)

When implementing HTTP endpoints, it is common to be operating with anio.Reader and anio.Writer. TheMarshalWrite andUnmarshalRead functionsassist in operating on such input/output types.UnmarshalRead reads the entirety of theio.Reader to ensure thatio.EOFis encountered without any unexpected bytes after the top-level JSON value.

package mainimport ("net/http""sync/atomic""github.com/go-json-experiment/json")func main() {// Some global state maintained by the server.var n int64// The "add" endpoint accepts a POST request with a JSON object// containing a number to atomically add to the server's global counter.// It returns the updated value of the counter.http.HandleFunc("/api/add", func(w http.ResponseWriter, r *http.Request) {// Unmarshal the request from the client.var val struct{ N int64 }if err := json.UnmarshalRead(r.Body, &val); err != nil {// Inability to unmarshal the input suggests a client-side problem.http.Error(w, err.Error(), http.StatusBadRequest)return}// Marshal a response from the server.val.N = atomic.AddInt64(&n, val.N)if err := json.MarshalWrite(w, &val); err != nil {// Inability to marshal the output suggests a server-side problem.// This error is not always observable by the client since// json.MarshalWrite may have already written to the output.http.Error(w, err.Error(), http.StatusInternalServerError)return}})}

Example (TextMarshal)

If a type implementsencoding.TextMarshaler and/orencoding.TextUnmarshaler,then the MarshalText and UnmarshalText methods are used to encode/decodethe value to/from a JSON string.

package mainimport ("fmt""log""net/netip""reflect""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {// Round-trip marshal and unmarshal a hostname map where the netip.Addr type// implements both encoding.TextMarshaler and encoding.TextUnmarshaler.want := map[netip.Addr]string{netip.MustParseAddr("192.168.0.100"): "carbonite",netip.MustParseAddr("192.168.0.101"): "obsidian",netip.MustParseAddr("192.168.0.102"): "diamond",}b, err := json.Marshal(&want, json.Deterministic(true))if err != nil {log.Fatal(err)}var got map[netip.Addr]stringerr = json.Unmarshal(b, &got)if err != nil {log.Fatal(err)}// Sanity check.if !reflect.DeepEqual(got, want) {log.Fatalf("roundtrip mismatch: got %v, want %v", got, want)}// Print the serialized JSON object.(*jsontext.Value)(&b).Indent() // indent for readabilityfmt.Println(string(b))}
Output:{"192.168.0.100": "carbonite","192.168.0.101": "obsidian","192.168.0.102": "diamond"}

Example (UnknownMembers)

Due to version skew, the set of JSON object members known at compile-timemay differ from the set of members encountered at execution-time.As such, it may be useful to have finer grain handling of unknown members.This package supports preserving, rejecting, or discarding such members.

package mainimport ("errors""fmt""log""strconv""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {const input = `{"Name": "Teal","Value": "#008080","WebSafe": false}`type Color struct {Name  stringValue string// Unknown is a Go struct field that holds unknown JSON object members.// It is marked as having this behavior with the "unknown" tag option.//// The type may be a jsontext.Value or map[string]T.Unknown jsontext.Value `json:",unknown"`}// By default, unknown members are stored in a Go field marked as "unknown"// or ignored if no such field exists.var color Colorerr := json.Unmarshal([]byte(input), &color)if err != nil {log.Fatal(err)}fmt.Println("Unknown members:", string(color.Unknown))// Specifying RejectUnknownMembers causes Unmarshal// to reject the presence of any unknown members.err = json.Unmarshal([]byte(input), new(Color), json.RejectUnknownMembers(true))var serr *json.SemanticErrorok := errors.As(err, &serr)if ok && serr.Err == json.ErrUnknownName {fmt.Println("Unmarshal error:", serr.Err, strconv.Quote(serr.JSONPointer.LastToken()))}// By default, Marshal preserves unknown members stored in// a Go struct field marked as "unknown".b, err := json.Marshal(color)if err != nil {log.Fatal(err)}fmt.Println("Output with unknown members:   ", string(b))// Specifying DiscardUnknownMembers causes Marshal// to discard any unknown members.b, err = json.Marshal(color, json.DiscardUnknownMembers(true))if err != nil {log.Fatal(err)}fmt.Println("Output without unknown members:", string(b))}
Output:Unknown members: {"WebSafe":false}Unmarshal error: unknown object member name "WebSafe"Output with unknown members:    {"Name":"Teal","Value":"#008080","WebSafe":false}Output without unknown members: {"Name":"Teal","Value":"#008080"}

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUnknownName =errors.New("unknown object member name")

ErrUnknownName indicates that a JSON object member could not beunmarshaled because the name is not known to the target Go struct.This error is directly wrapped within aSemanticError when produced.

The name of an unknown JSON object member can be extracted as:

err := ...serr, ok := errors.AsType[*json.SemanticError](err)if ok && serr.Err == json.ErrUnknownName {ptr := serr.JSONPointer // JSON pointer to unknown namename := ptr.LastToken() // unknown name itself...}

This error is only returned ifRejectUnknownMembers is true.

View Source
var SkipFunc =errors.New("json: skip function")

SkipFunc may be returned byMarshalToFunc andUnmarshalFromFunc functions.

Any function that returns SkipFunc must not cause observable side effectson the providedjsontext.Encoder orjsontext.Decoder.For example, it is permissible to calljsontext.Decoder.PeekKind,but not permissible to calljsontext.Decoder.ReadToken orjsontext.Encoder.WriteToken since such methods mutate the state.

Functions

funcGetOption

func GetOption[Tany](optsOptions, setter func(T)Options) (T,bool)

GetOption returns the value stored in opts with the provided setter,reporting whether the value is present.

Example usage:

v, ok := json.GetOption(opts, json.Deterministic)

Options are most commonly introspected to alter the JSON representation of[MarshalerTo.MarshalJSONTo] and [UnmarshalerFrom.UnmarshalJSONFrom] methods, andMarshalToFunc andUnmarshalFromFunc functions.In such cases, the presence bit should generally be ignored.

funcMarshal

func Marshal(inany, opts ...Options) (out []byte, errerror)

Marshal serializes a Go value as a []byte according to the providedmarshal and encode options (while ignoring unmarshal or decode options).It does not terminate the output with a newline.

Type-specific marshal functions and methods take precedenceover the default representation of a value.Functions or methods that operate on *T are only called when encodinga value of type T (by taking its address) or a non-nil value of *T.Marshal ensures that a value is always addressable(by boxing it on the heap if necessary) so thatthese functions and methods can be consistently called. For performance,it is recommended that Marshal be passed a non-nil pointer to the value.

The input value is encoded as JSON according the following rules:

  • If any type-specific functions in aWithMarshalers option matchthe value type, then those functions are called to encode the value.If all applicable functions returnSkipFunc,then the value is encoded according to subsequent rules.

  • If the value type implementsMarshalerTo,then the MarshalJSONTo method is called to encode the value.

  • If the value type implementsMarshaler,then the MarshalJSON method is called to encode the value.

  • If the value type implementsencoding.TextAppender,then the AppendText method is called to encode the value andsubsequently encode its result as a JSON string.

  • If the value type implementsencoding.TextMarshaler,then the MarshalText method is called to encode the value andsubsequently encode its result as a JSON string.

  • Otherwise, the value is encoded according to the value's typeas described in detail below.

Most Go types have a default JSON representation.Certain types support specialized formatting according toa format flag optionally specified in the Go struct tagfor the struct field that contains the current value(see the “JSON Representation of Go structs” section for more details).

The representation of each type is as follows:

  • A Go boolean is encoded as a JSON boolean (e.g., true or false).It does not support any custom format flags.

  • A Go string is encoded as a JSON string.It does not support any custom format flags.

  • A Go []byte or [N]byte is encoded as a JSON string containingthe binary value encoded usingRFC 4648.If the format is "base64" or unspecified, then this usesRFC 4648, section 4.If the format is "base64url", then this usesRFC 4648, section 5.If the format is "base32", then this usesRFC 4648, section 6.If the format is "base32hex", then this usesRFC 4648, section 7.If the format is "base16" or "hex", then this usesRFC 4648, section 8.If the format is "array", then the bytes value is encoded as a JSON arraywhere each byte is recursively JSON-encoded as each JSON array element.

  • A Go integer is encoded as a JSON number without fractions or exponents.IfStringifyNumbers is specified or encoding a JSON object name,then the JSON number is encoded within a JSON string.It does not support any custom format flags.

  • A Go float is encoded as a JSON number.IfStringifyNumbers is specified or encoding a JSON object name,then the JSON number is encoded within a JSON string.If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded asthe JSON strings "NaN", "Infinity", and "-Infinity", respectively.Otherwise, the presence of non-finite numbers results in aSemanticError.

  • A Go map is encoded as a JSON object, where each Go map key and valueis recursively encoded as a name and value pair in the JSON object.The Go map key must encode as a JSON string, otherwise this resultsin aSemanticError. The Go map is traversed in a non-deterministic order.For deterministic encoding, consider using theDeterministic option.If the format is "emitnull", then a nil map is encoded as a JSON null.If the format is "emitempty", then a nil map is encoded as an empty JSON object,regardless of whetherFormatNilMapAsNull is specified.Otherwise by default, a nil map is encoded as an empty JSON object.

  • A Go struct is encoded as a JSON object.See the “JSON Representation of Go structs” sectionin the package-level documentation for more details.

  • A Go slice is encoded as a JSON array, where each Go slice elementis recursively JSON-encoded as the elements of the JSON array.If the format is "emitnull", then a nil slice is encoded as a JSON null.If the format is "emitempty", then a nil slice is encoded as an empty JSON array,regardless of whetherFormatNilSliceAsNull is specified.Otherwise by default, a nil slice is encoded as an empty JSON array.

  • A Go array is encoded as a JSON array, where each Go array elementis recursively JSON-encoded as the elements of the JSON array.The JSON array length is always identical to the Go array length.It does not support any custom format flags.

  • A Go pointer is encoded as a JSON null if nil, otherwise it isthe recursively JSON-encoded representation of the underlying value.Format flags are forwarded to the encoding of the underlying value.

  • A Go interface is encoded as a JSON null if nil, otherwise it isthe recursively JSON-encoded representation of the underlying value.It does not support any custom format flags.

  • A Gotime.Time is encoded as a JSON string containing the timestampformatted inRFC 3339 with nanosecond precision.If the format matches one of the format constants declaredin the time package (e.g., RFC1123), then that format is used.If the format is "unix", "unixmilli", "unixmicro", or "unixnano",then the timestamp is encoded as a possibly fractional JSON numberof the number of seconds (or milliseconds, microseconds, or nanoseconds)since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.To avoid a fractional component, round the timestamp to the relevant unit.Otherwise, the format is used as-is withtime.Time.Format if non-empty.

  • A Gotime.Duration currently has no default representation andrequires an explicit format to be specified.If the format is "sec", "milli", "micro", or "nano",then the duration is encoded as a possibly fractional JSON numberof the number of seconds (or milliseconds, microseconds, or nanoseconds).To avoid a fractional component, round the duration to the relevant unit.If the format is "units", it is encoded as a JSON string formatted usingtime.Duration.String (e.g., "1h30m" for 1 hour 30 minutes).If the format is "iso8601", it is encoded as a JSON string using theISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)using only accurate units of hours, minutes, and seconds.

  • All other Go types (e.g., complex numbers, channels, and functions)have no default representation and result in aSemanticError.

JSON cannot represent cyclic data structures and Marshal does not handle them.Passing cyclic structures will result in an error.

funcMarshalEncode

func MarshalEncode(out *jsontext.Encoder, inany, opts ...Options) (errerror)

MarshalEncode serializes a Go value into anjsontext.Encoder according tothe provided marshal options (while ignoring unmarshal, encode, or decode options).Any marshal-relevant options already specified on thejsontext.Encodertake lower precedence than the set of options provided by the caller.UnlikeMarshal andMarshalWrite, encode options are ignored becausethey must have already been specified on the providedjsontext.Encoder.

SeeMarshal for details about the conversion of a Go value into JSON.

funcMarshalWrite

func MarshalWrite(outio.Writer, inany, opts ...Options) (errerror)

MarshalWrite serializes a Go value into anio.Writer according to the providedmarshal and encode options (while ignoring unmarshal or decode options).It does not terminate the output with a newline.SeeMarshal for details about the conversion of a Go value into JSON.

funcUnmarshal

func Unmarshal(in []byte, outany, opts ...Options) (errerror)

Unmarshal decodes a []byte input into a Go value according to the providedunmarshal and decode options (while ignoring marshal or encode options).The input must be a single JSON value with optional whitespace interspersed.The output must be a non-nil pointer.

Type-specific unmarshal functions and methods take precedenceover the default representation of a value.Functions or methods that operate on *T are only called when decodinga value of type T (by taking its address) or a non-nil value of *T.Unmarshal ensures that a value is always addressable(by boxing it on the heap if necessary) so thatthese functions and methods can be consistently called.

The input is decoded into the output according the following rules:

  • If any type-specific functions in aWithUnmarshalers option matchthe value type, then those functions are called to decode the JSONvalue. If all applicable functions returnSkipFunc,then the input is decoded according to subsequent rules.

  • If the value type implementsUnmarshalerFrom,then the UnmarshalJSONFrom method is called to decode the JSON value.

  • If the value type implementsUnmarshaler,then the UnmarshalJSON method is called to decode the JSON value.

  • If the value type implementsencoding.TextUnmarshaler,then the input is decoded as a JSON string andthe UnmarshalText method is called with the decoded string value.This fails with aSemanticError if the input is not a JSON string.

  • Otherwise, the JSON value is decoded according to the value's typeas described in detail below.

Most Go types have a default JSON representation.Certain types support specialized formatting according toa format flag optionally specified in the Go struct tagfor the struct field that contains the current value(see the “JSON Representation of Go structs” section for more details).A JSON null may be decoded into every supported Go value whereit is equivalent to storing the zero value of the Go value.If the input JSON kind is not handled by the current Go value type,then this fails with aSemanticError. Unless otherwise specified,the decoded value replaces any pre-existing value.

The representation of each type is as follows:

  • A Go boolean is decoded from a JSON boolean (e.g., true or false).It does not support any custom format flags.

  • A Go string is decoded from a JSON string.It does not support any custom format flags.

  • A Go []byte or [N]byte is decoded from a JSON stringcontaining the binary value encoded usingRFC 4648.If the format is "base64" or unspecified, then this usesRFC 4648, section 4.If the format is "base64url", then this usesRFC 4648, section 5.If the format is "base32", then this usesRFC 4648, section 6.If the format is "base32hex", then this usesRFC 4648, section 7.If the format is "base16" or "hex", then this usesRFC 4648, section 8.If the format is "array", then the Go slice or array is decoded from aJSON array where each JSON element is recursively decoded for each byte.When decoding into a non-nil []byte, the slice length is reset to zeroand the decoded input is appended to it.When decoding into a [N]byte, the input must decode to exactly N bytes,otherwise it fails with aSemanticError.

  • A Go integer is decoded from a JSON number.It must be decoded from a JSON string containing a JSON numberifStringifyNumbers is specified or decoding a JSON object name.It fails with aSemanticError if the JSON numberhas a fractional or exponent component.It also fails if it overflows the representation of the Go integer type.It does not support any custom format flags.

  • A Go float is decoded from a JSON number.It must be decoded from a JSON string containing a JSON numberifStringifyNumbers is specified or decoding a JSON object name.It fails if it overflows the representation of the Go float type.If the format is "nonfinite", then the JSON strings"NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf.Otherwise, the presence of such strings results in aSemanticError.

  • A Go map is decoded from a JSON object,where each JSON object name and value pair is recursively decodedas the Go map key and value. Maps are not cleared.If the Go map is nil, then a new map is allocated to decode into.If the decoded key matches an existing Go map entry, the entry valueis reused by decoding the JSON object value into it.The formats "emitnull" and "emitempty" have no effect when decoding.

  • A Go struct is decoded from a JSON object.See the “JSON Representation of Go structs” sectionin the package-level documentation for more details.

  • A Go slice is decoded from a JSON array, where each JSON elementis recursively decoded and appended to the Go slice.Before appending into a Go slice, a new slice is allocated if it is nil,otherwise the slice length is reset to zero.The formats "emitnull" and "emitempty" have no effect when decoding.

  • A Go array is decoded from a JSON array, where each JSON array elementis recursively decoded as each corresponding Go array element.Each Go array element is zeroed before decoding into it.It fails with aSemanticError if the JSON array does not containthe exact same number of elements as the Go array.It does not support any custom format flags.

  • A Go pointer is decoded based on the JSON kind and underlying Go type.If the input is a JSON null, then this stores a nil pointer.Otherwise, it allocates a new underlying value if the pointer is nil,and recursively JSON decodes into the underlying value.Format flags are forwarded to the decoding of the underlying type.

  • A Go interface is decoded based on the JSON kind and underlying Go type.If the input is a JSON null, then this stores a nil interface value.Otherwise, a nil interface value of an empty interface type is initializedwith a zero Go bool, string, float64, map[string]any, or []any if theinput is a JSON boolean, string, number, object, or array, respectively.If the interface value is still nil, then this fails with aSemanticErrorsince decoding could not determine an appropriate Go type to decode into.For example, unmarshaling into a nil io.Reader fails sincethere is no concrete type to populate the interface value with.Otherwise an underlying value exists and it recursively decodesthe JSON input into it. It does not support any custom format flags.

  • A Gotime.Time is decoded from a JSON string containing the timeformatted inRFC 3339 with nanosecond precision.If the format matches one of the format constants declared inthe time package (e.g., RFC1123), then that format is used for parsing.If the format is "unix", "unixmilli", "unixmicro", or "unixnano",then the timestamp is decoded from an optionally fractional JSON numberof the number of seconds (or milliseconds, microseconds, or nanoseconds)since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC.Otherwise, the format is used as-is withtime.Time.Parse if non-empty.

  • A Gotime.Duration currently has no default representation andrequires an explicit format to be specified.If the format is "sec", "milli", "micro", or "nano",then the duration is decoded from an optionally fractional JSON numberof the number of seconds (or milliseconds, microseconds, or nanoseconds).If the format is "units", it is decoded from a JSON string parsed usingtime.ParseDuration (e.g., "1h30m" for 1 hour 30 minutes).If the format is "iso8601", it is decoded from a JSON string using theISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes)accepting only accurate units of hours, minutes, or seconds.

  • All other Go types (e.g., complex numbers, channels, and functions)have no default representation and result in aSemanticError.

In general, unmarshaling follows merge semantics (similar toRFC 7396)where the decoded Go value replaces the destination valuefor any JSON kind other than an object.For JSON objects, the input object is merged into the destination valuewhere matching object members recursively apply merge semantics.

funcUnmarshalDecode

func UnmarshalDecode(in *jsontext.Decoder, outany, opts ...Options) (errerror)

UnmarshalDecode deserializes a Go value from ajsontext.Decoder according tothe provided unmarshal options (while ignoring marshal, encode, or decode options).Any unmarshal options already specified on thejsontext.Decodertake lower precedence than the set of options provided by the caller.UnlikeUnmarshal andUnmarshalRead, decode options are ignored becausethey must have already been specified on the providedjsontext.Decoder.

The input may be a stream of zero or more JSON values,where this only unmarshals the next JSON value in the stream.If there are no more top-level JSON values, it reportsio.EOF.The output must be a non-nil pointer.SeeUnmarshal for details about the conversion of JSON into a Go value.

funcUnmarshalRead

func UnmarshalRead(inio.Reader, outany, opts ...Options) (errerror)

UnmarshalRead deserializes a Go value from anio.Reader according to theprovided unmarshal and decode options (while ignoring marshal or encode options).The input must be a single JSON value with optional whitespace interspersed.It consumes the entirety ofio.Reader untilio.EOF is encountered,without reporting an error for EOF. The output must be a non-nil pointer.SeeUnmarshal for details about the conversion of JSON into a Go value.

Types

typeMarshaler

type Marshaler interface {MarshalJSON() ([]byte,error)}

Marshaler is implemented by types that can marshal themselves.It is recommended that types implementMarshalerTo unless the implementationis trying to avoid a hard dependency on the "jsontext" package.

It is recommended that implementations return a buffer that is safefor the caller to retain and potentially mutate.

If the returned error is aSemanticError, then unpopulated fieldsof the error may be populated byjson with additional context.Errors of other types are wrapped within aSemanticError.

typeMarshalerTo

type MarshalerTo interface {MarshalJSONTo(*jsontext.Encoder)error}

MarshalerTo is implemented by types that can marshal themselves.It is recommended that types implement MarshalerTo instead ofMarshalersince this is both more performant and flexible.If a type implements both Marshaler and MarshalerTo,then MarshalerTo takes precedence. In such a case, both implementationsshould aim to have equivalent behavior for the default marshal options.

The implementation must write only one JSON value to the Encoder andmust not retain the pointer tojsontext.Encoder.

If the returned error is aSemanticError, then unpopulated fieldsof the error may be populated byjson with additional context.Errors of other types are wrapped within aSemanticError,unless it is an IO error.

typeMarshalers

type Marshalers = typedMarshalers

Marshalers is a list of functions that may override the marshal behaviorof specific types. PopulateWithMarshalers to use it withMarshal,MarshalWrite, orMarshalEncode.A nil *Marshalers is equivalent to an empty list.There are no exported fields or methods on Marshalers.

funcJoinMarshalers

func JoinMarshalers(ms ...*Marshalers) *Marshalers

JoinMarshalers constructs a flattened list of marshal functions.If multiple functions in the list are applicable for a value of a given type,then those earlier in the list take precedence over those that come later.If a function returnsSkipFunc, then the next applicable function is called,otherwise the default marshaling behavior is used.

For example:

m1 := JoinMarshalers(f1, f2)m2 := JoinMarshalers(f0, m1, f3)     // equivalent to m3m3 := JoinMarshalers(f0, f1, f2, f3) // equivalent to m2

funcMarshalFunc

func MarshalFunc[Tany](fn func(T) ([]byte,error)) *Marshalers

MarshalFunc constructs a type-specific marshaler thatspecifies how to marshal values of type T.T can be any type except a named pointer.The function is always provided with a non-nil pointer valueif T is an interface or pointer type.

The function must marshal exactly one JSON value.The value of T must not be retained outside the function call.It may not returnSkipFunc.

funcMarshalToFunc

func MarshalToFunc[Tany](fn func(*jsontext.Encoder, T)error) *Marshalers

MarshalToFunc constructs a type-specific marshaler thatspecifies how to marshal values of type T.T can be any type except a named pointer.The function is always provided with a non-nil pointer valueif T is an interface or pointer type.

The function must marshal exactly one JSON value by calling write methodson the provided encoder. It may returnSkipFunc such that marshaling canmove on to the next marshal function. However, no mutable method calls maybe called on the encoder ifSkipFunc is returned.The pointer tojsontext.Encoder and the value of Tmust not be retained outside the function call.

typeOptions

type Options =jsonopts.Options

Options configureMarshal,MarshalWrite,MarshalEncode,Unmarshal,UnmarshalRead, andUnmarshalDecode with specific features.Each function takes in a variadic list of options, where propertiesset in later options override the value of previously set properties.

The Options type is identical toencoding/json.Options andencoding/json/jsontext.Options. Options from the other packages canbe used interchangeably with functionality in this package.

Options represent either a singular option or a set of options.It can be functionally thought of as a Go map of option properties(even though the underlying implementation avoids Go maps for performance).

The constructors (e.g.,Deterministic) return a singular option value:

opt := Deterministic(true)

which is analogous to creating a single entry map:

opt := Options{"Deterministic": true}

JoinOptions composes multiple options values to together:

out := JoinOptions(opts...)

which is analogous to making a new map and copying the options over:

out := make(Options)for _, m := range opts {for k, v := range m {out[k] = v}}

GetOption looks up the value of options parameter:

v, ok := GetOption(opts, Deterministic)

which is analogous to a Go map lookup:

v, ok := Options["Deterministic"]

There is a single Options type, which is used with both marshal and unmarshal.Some options affect both operations, while others only affect one operation:

Options that do not affect a particular operation are ignored.

funcDefaultOptionsV2

func DefaultOptionsV2()Options

DefaultOptionsV2 is the full set of all options that define v2 semantics.It is equivalent to the set of options inencoding/json.DefaultOptionsV1all being set to false. All other options are not present.

funcDeterministic

func Deterministic(vbool)Options

Deterministic specifies that the same input value will be serializedas the exact same output bytes. Different processes ofthe same program will serialize equal values to the same bytes,but different versions of the same program are not guaranteedto produce the exact same sequence of bytes.

This only affects marshaling and is ignored when unmarshaling.

funcDiscardUnknownMembers

func DiscardUnknownMembers(vbool)Options

DiscardUnknownMembers specifies that marshaling should ignore anyJSON object members stored in Go struct fields dedicated to storingunknown JSON object members.

This only affects marshaling and is ignored when unmarshaling.

funcFormatNilMapAsNull

func FormatNilMapAsNull(vbool)Options

FormatNilMapAsNull specifies that a nil Go map should marshal as aJSON null instead of the default representation as an empty JSON object.Map fields explicitly marked with `format:emitempty` still marshalas an empty JSON object.

This only affects marshaling and is ignored when unmarshaling.

funcFormatNilSliceAsNull

func FormatNilSliceAsNull(vbool)Options

FormatNilSliceAsNull specifies that a nil Go slice should marshal as aJSON null instead of the default representation as an empty JSON array(or an empty JSON string in the case of ~[]byte).Slice fields explicitly marked with `format:emitempty` still marshalas an empty JSON array.

This only affects marshaling and is ignored when unmarshaling.

funcJoinOptions

func JoinOptions(srcs ...Options)Options

JoinOptions coalesces the provided list of options into a single Options.Properties set in later options override the value of previously set properties.

funcMatchCaseInsensitiveNames

func MatchCaseInsensitiveNames(vbool)Options

MatchCaseInsensitiveNames specifies that JSON object members are matchedagainst Go struct fields using a case-insensitive match of the name.Go struct fields explicitly marked with `case:strict` or `case:ignore`always use case-sensitive (or case-insensitive) name matching,regardless of the value of this option.

This affects either marshaling or unmarshaling.For marshaling, this option may alter the detection of duplicate names(assumingjsontext.AllowDuplicateNames is false) from inlined fieldsif it matches one of the declared fields in the Go struct.

funcOmitZeroStructFields

func OmitZeroStructFields(vbool)Options

OmitZeroStructFields specifies that a Go struct should marshal in such a waythat all struct fields that are zero are omitted from the marshaled outputif the value is zero as determined by the "IsZero() bool" method if present,otherwise based on whether the field is the zero Go value.This is semantically equivalent to specifying the `omitzero` tag optionon every field in a Go struct.

This only affects marshaling and is ignored when unmarshaling.

funcRejectUnknownMembers

func RejectUnknownMembers(vbool)Options

RejectUnknownMembers specifies that unknown members should be rejectedwhen unmarshaling a JSON object, regardless of whether there is a fieldto store unknown members.

This only affects unmarshaling and is ignored when marshaling.

funcStringifyNumbers

func StringifyNumbers(vbool)Options

StringifyNumbers specifies that numeric Go types should be marshaledas a JSON string containing the equivalent JSON number value.When unmarshaling, numeric Go types are parsed from a JSON stringcontaining the JSON number without any surrounding whitespace.

According toRFC 8259, section 6, a JSON implementation may choose tolimit the representation of a JSON number to an IEEE 754 binary64 value.This may cause decoders to lose precision for int64 and uint64 types.Quoting JSON numbers as a JSON string preserves the exact precision.

This affects either marshaling or unmarshaling.

funcWithMarshalers

func WithMarshalers(v *Marshalers)Options

WithMarshalers specifies a list of type-specific marshalers to use,which can be used to override the default marshal behavior for valuesof particular types.

This only affects marshaling and is ignored when unmarshaling.

Example (Errors)

Many error types are not serializable since they tend to be Go structswithout any exported fields (e.g., errors constructed witherrors.New).Some applications, may desire to marshal an error as a JSON stringeven if these errors cannot be unmarshaled.

package mainimport ("fmt""log""os""strconv""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {// Response to serialize with some Go errors encountered.response := []struct {Result string `json:",omitzero"`Error  error  `json:",omitzero"`}{{Result: "Oranges are a good source of Vitamin C."},{Error: &strconv.NumError{Func: "ParseUint", Num: "-1234", Err: strconv.ErrSyntax}},{Error: &os.PathError{Op: "ReadFile", Path: "/path/to/secret/file", Err: os.ErrPermission}},}b, err := json.Marshal(&response,// Intercept every attempt to marshal an error type.json.WithMarshalers(json.JoinMarshalers(// Suppose we consider strconv.NumError to be a safe to serialize:// this type-specific marshal function intercepts this type// and encodes the error message as a JSON string.json.MarshalToFunc(func(enc *jsontext.Encoder, err *strconv.NumError) error {return enc.WriteToken(jsontext.String(err.Error()))}),// Error messages may contain sensitive information that may not// be appropriate to serialize. For all errors not handled above,// report some generic error message.json.MarshalFunc(func(error) ([]byte, error) {return []byte(`"internal server error"`), nil}),)),jsontext.Multiline(true)) // expand for readabilityif err != nil {log.Fatal(err)}fmt.Println(string(b))}
Output:[{"Result": "Oranges are a good source of Vitamin C."},{"Error": "strconv.ParseUint: parsing \"-1234\": invalid syntax"},{"Error": "internal server error"}]

funcWithUnmarshalers

func WithUnmarshalers(v *Unmarshalers)Options

WithUnmarshalers specifies a list of type-specific unmarshalers to use,which can be used to override the default unmarshal behavior for valuesof particular types.

This only affects unmarshaling and is ignored when marshaling.

Example (RawNumber)

In some applications, the exact precision of JSON numbers needs to bepreserved when unmarshaling. This can be accomplished using a type-specificunmarshal function that intercepts all any types and pre-populates theinterface value with ajsontext.Value, which can represent a JSON number exactly.

package mainimport ("fmt""log""reflect""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {// Input with JSON numbers beyond the representation of a float64.const input = `[false, 1e-1000, 3.141592653589793238462643383279, 1e+1000, true]`var value anyerr := json.Unmarshal([]byte(input), &value,// Intercept every attempt to unmarshal into the any type.json.WithUnmarshalers(json.UnmarshalFromFunc(func(dec *jsontext.Decoder, val *any) error {// If the next value to be decoded is a JSON number,// then provide a concrete Go type to unmarshal into.if dec.PeekKind() == '0' {*val = jsontext.Value(nil)}// Return SkipFunc to fallback on default unmarshal behavior.return json.SkipFunc}),))if err != nil {log.Fatal(err)}fmt.Println(value)// Sanity check.want := []any{false, jsontext.Value("1e-1000"), jsontext.Value("3.141592653589793238462643383279"), jsontext.Value("1e+1000"), true}if !reflect.DeepEqual(value, want) {log.Fatalf("value mismatch:\ngot  %v\nwant %v", value, want)}}
Output:[false 1e-1000 3.141592653589793238462643383279 1e+1000 true]

Example (RecordOffsets)

When using JSON for parsing configuration files,the parsing logic often needs to report an error with a line and columnindicating where in the input an error occurred.

package mainimport ("bytes""fmt""log""net/netip""strings""github.com/go-json-experiment/json""github.com/go-json-experiment/json/jsontext")func main() {// Hypothetical configuration file.const input = `[{"Source": "192.168.0.100:1234", "Destination": "192.168.0.1:80"},{"Source": "192.168.0.251:4004"},{"Source": "192.168.0.165:8080", "Destination": "0.0.0.0:80"}]`type Tunnel struct {Source      netip.AddrPortDestination netip.AddrPort// ByteOffset is populated during unmarshal with the byte offset// within the JSON input of the JSON object for this Go struct.ByteOffset int64 `json:"-"` // metadata to be ignored for JSON serialization}var tunnels []Tunnelerr := json.Unmarshal([]byte(input), &tunnels,// Intercept every attempt to unmarshal into the Tunnel type.json.WithUnmarshalers(json.UnmarshalFromFunc(func(dec *jsontext.Decoder, tunnel *Tunnel) error {// Decoder.InputOffset reports the offset after the last token,// but we want to record the offset before the next token.//// Call Decoder.PeekKind to buffer enough to reach the next token.// Add the number of leading whitespace, commas, and colons// to locate the start of the next token.dec.PeekKind()unread := dec.UnreadBuffer()n := len(unread) - len(bytes.TrimLeft(unread, " \n\r\t,:"))tunnel.ByteOffset = dec.InputOffset() + int64(n)// Return SkipFunc to fallback on default unmarshal behavior.return json.SkipFunc}),))if err != nil {log.Fatal(err)}// lineColumn converts a byte offset into a one-indexed line and column.// The offset must be within the bounds of the input.lineColumn := func(input string, offset int) (line, column int) {line = 1 + strings.Count(input[:offset], "\n")column = 1 + offset - (strings.LastIndex(input[:offset], "\n") + len("\n"))return line, column}// Verify that the configuration file is valid.for _, tunnel := range tunnels {if !tunnel.Source.IsValid() || !tunnel.Destination.IsValid() {line, column := lineColumn(input, int(tunnel.ByteOffset))fmt.Printf("%d:%d: source and destination must both be specified", line, column)}}}
Output:3:3: source and destination must both be specified

typeSemanticError

type SemanticError struct {// ByteOffset indicates that an error occurred after this byte offset.ByteOffsetint64// JSONPointer indicates that an error occurred within this JSON value// as indicated using the JSON Pointer notation (seeRFC 6901).JSONPointerjsontext.Pointer// JSONKind is the JSON kind that could not be handled.JSONKindjsontext.Kind// may be zero if unknown// JSONValue is the JSON number or string that could not be unmarshaled.// It is not populated during marshaling.JSONValuejsontext.Value// may be nil if irrelevant or unknown// GoType is the Go type that could not be handled.GoTypereflect.Type// may be nil if unknown// Err is the underlying error.Errerror// may be nil// contains filtered or unexported fields}

SemanticError describes an error determining the meaningof JSON data as Go data or vice-versa.

If aMarshaler,MarshalerTo,Unmarshaler, orUnmarshalerFrom methodreturns a SemanticError when called by thejson package,then the ByteOffset, JSONPointer, and GoType fields are automaticallypopulated by the calling context if they are the zero value.

The contents of this error as produced by this package may change over time.

func (*SemanticError)Error

func (e *SemanticError) Error()string

func (*SemanticError)Unwrap

func (e *SemanticError) Unwrap()error

typeUnmarshaler

type Unmarshaler interface {UnmarshalJSON([]byte)error}

Unmarshaler is implemented by types that can unmarshal themselves.It is recommended that types implementUnmarshalerFrom unless the implementationis trying to avoid a hard dependency on the "jsontext" package.

The input can be assumed to be a valid encoding of a JSON valueif called from unmarshal functionality in this package.UnmarshalJSON must copy the JSON data if it is retained after returning.It is recommended that UnmarshalJSON implement merge semantics whenunmarshaling into a pre-populated value.

Implementations must not retain or mutate the input []byte.

If the returned error is aSemanticError, then unpopulated fieldsof the error may be populated byjson with additional context.Errors of other types are wrapped within aSemanticError.

typeUnmarshalerFrom

type UnmarshalerFrom interface {UnmarshalJSONFrom(*jsontext.Decoder)error}

UnmarshalerFrom is implemented by types that can unmarshal themselves.It is recommended that types implement UnmarshalerFrom instead ofUnmarshalersince this is both more performant and flexible.If a type implements both Unmarshaler and UnmarshalerFrom,then UnmarshalerFrom takes precedence. In such a case, both implementationsshould aim to have equivalent behavior for the default unmarshal options.

The implementation must read only one JSON value from the Decoder.It is recommended that UnmarshalJSONFrom implement merge semantics whenunmarshaling into a pre-populated value.

Implementations must not retain the pointer tojsontext.Decoder.

If the returned error is aSemanticError, then unpopulated fieldsof the error may be populated byjson with additional context.Errors of other types are wrapped within aSemanticError,unless it is ajsontext.SyntacticError or an IO error.

typeUnmarshalers

type Unmarshalers = typedUnmarshalers

Unmarshalers is a list of functions that may override the unmarshal behaviorof specific types. PopulateWithUnmarshalers to use it withUnmarshal,UnmarshalRead, orUnmarshalDecode.A nil *Unmarshalers is equivalent to an empty list.There are no exported fields or methods on Unmarshalers.

funcJoinUnmarshalers

func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers

JoinUnmarshalers constructs a flattened list of unmarshal functions.If multiple functions in the list are applicable for a value of a given type,then those earlier in the list take precedence over those that come later.If a function returnsSkipFunc, then the next applicable function is called,otherwise the default unmarshaling behavior is used.

For example:

u1 := JoinUnmarshalers(f1, f2)u2 := JoinUnmarshalers(f0, u1, f3)     // equivalent to u3u3 := JoinUnmarshalers(f0, f1, f2, f3) // equivalent to u2

funcUnmarshalFromFunc

func UnmarshalFromFunc[Tany](fn func(*jsontext.Decoder, T)error) *Unmarshalers

UnmarshalFromFunc constructs a type-specific unmarshaler thatspecifies how to unmarshal values of type T.T must be an unnamed pointer or an interface type.The function is always provided with a non-nil pointer value.

The function must unmarshal exactly one JSON value by calling read methodson the provided decoder. It may returnSkipFunc such that unmarshaling canmove on to the next unmarshal function. However, no mutable method calls maybe called on the decoder ifSkipFunc is returned.The pointer tojsontext.Decoder and the value of Tmust not be retained outside the function call.

funcUnmarshalFunc

func UnmarshalFunc[Tany](fn func([]byte, T)error) *Unmarshalers

UnmarshalFunc constructs a type-specific unmarshaler thatspecifies how to unmarshal values of type T.T must be an unnamed pointer or an interface type.The function is always provided with a non-nil pointer value.

The function must unmarshal exactly one JSON value.The input []byte must not be mutated.The input []byte and value T must not be retained outside the function call.It may not returnSkipFunc.

Source Files

View all Source files

Directories

PathSynopsis
jsonflags
jsonflags implements all the optional boolean flags.
jsonflags implements all the optional boolean flags.
jsontest
Package jsontest contains functionality to assist in testing JSON.
Package jsontest contains functionality to assist in testing JSON.
jsonwire
Package jsonwire implements stateless functionality for handling JSON text.
Package jsonwire implements stateless functionality for handling JSON text.
zstd
Package zstd provides a decompressor for zstd streams, described in RFC 8878.
Package zstd provides a decompressor for zstd streams, described in RFC 8878.
Package jsontext implements syntactic processing of JSON as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785.
Package jsontext implements syntactic processing of JSON as specified in RFC 4627, RFC 7159, RFC 7493, RFC 8259, and RFC 8785.
Package json implements encoding and decoding of JSON as defined in RFC 7159.
Package json implements encoding and decoding of JSON as defined in RFC 7159.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp