encoding/json: document Unmarshal behavior of JSON arrays into non-empty Go slices

The documented behavior of how JSON arrays are unmarshaled
into non-empty Go slices does not match the actual implementation.
Document the real behavior.

Fixes #21092

Change-Id: I1097951f4e691a5eda4eccdb8bc6d767910219cf
Reviewed-on: https://go-review.googlesource.com/c/go/+/772760
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
Joe Tsai 2026-04-30 15:43:51 -07:00 committed by Joseph Tsai
parent 0af7dbf1e6
commit f1bc06b98d
3 changed files with 11 additions and 4 deletions

View file

@ -61,8 +61,10 @@ import (
// - map[string]any, for JSON objects
// - nil for JSON null
//
// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.
// To unmarshal a JSON array into a slice, Unmarshal decodes each JSON array
// element into the corresponding slice element, reusing existing slice
// elements in-place. The slice grows to accommodate additional elements,
// or is truncated if the JSON array is shorter.
// As a special case, to unmarshal an empty JSON array into a slice,
// Unmarshal replaces the slice with a new empty slice.
//

View file

@ -58,8 +58,10 @@ import (
// - map[string]any, for JSON objects
// - nil for JSON null
//
// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.
// To unmarshal a JSON array into a slice, Unmarshal decodes each JSON array
// element into the corresponding slice element, reusing existing slice
// elements in-place. The slice grows to accommodate additional elements,
// or is truncated if the JSON array is shorter.
// As a special case, to unmarshal an empty JSON array into a slice,
// Unmarshal replaces the slice with a new empty slice.
//

View file

@ -371,6 +371,9 @@ func MatchCaseSensitiveDelimiter(v bool) Options {
// the original Go value for array elements, slice elements,
// struct fields (but not map values),
// pointer values, and interface values (only if a non-nil pointer).
// For slices, it will merge into the pre-existing value of slice elements
// even for those past the slice length. If the original slice length
// was longer than the JSON array, then it is truncated to match.
// In contrast, the default v2 behavior is to merge into the Go value
// for struct fields, map values, pointer values, and interface values.
// In general, the v2 semantic merges when unmarshaling a JSON object,