当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


GO Marshal用法及代码示例


GO语言"encoding/json"包中"Marshal"函数的用法及代码示例。

用法:

func Marshal(v any)([]byte, error)

Marshal 返回 v 的 JSON 编码。

Marshal 递归地遍历值 v。如果遇到的值实现了 Marshaler 接口并且不是 nil 指针,则 Marshal 调用其MarshalJSON 方法来生成 JSON。如果不存在 MarshalJSON 方法,但该值实现了编码 TextMarshaler,则 Marshal 调用其 MarshalText 方法并将结果编码为 JSON 字符串。 nil 指针异常不是绝对必要的,但在UnmarshalJSON 的行为中模仿了类似的必要异常

否则,Marshal 使用以下 type-dependent 默认编码:

布尔值编码为 JSON 布尔值。

浮点、整数和数字值编码为 JSON 数字。

字符串值编码为强制转换为有效 UTF-8 的 JSON 字符串,用 Unicode 替换符文替换无效字节。为了让 JSON 可以安全地嵌入 HTML <script> 标记,字符串使用 HTMLEscape 进行编码,替换 "<"、">"、"&"、U+2028 和 U+2029 转义为 "\u003c","\u003e"、"\u0026"、"\u2028" 和 "\u2029"。使用编码器时,可以通过调用 SetEscapeHTML(false) 禁用此替换。

数组和切片值编码为 JSON 数组,除了 []byte 编码为 base64 编码字符串,nil 切片编码为空 JSON 值。

结构值编码为 JSON 对象。每个导出的结构字段都成为对象的成员,使用字段名称作为对象键,除非由于以下原因之一省略了该字段。

每个结构字段的编码可以通过存储在结构字段标签中"json"键下的格式字符串进行自定义。格式字符串给出了字段的名称,可能后跟以逗号分隔的选项列表。名称可以为空,以便在不覆盖默认字段名称的情况下指定选项。

"omitempty" 选项指定如果字段具有空值(定义为 false、0、nil 指针、nil 接口值以及任何空数组、切片、映射或字符串),则应从编码中省略该字段。

作为一种特殊情况,如果字段标记为"-",则始终省略该字段。请注意,名称为"-" 的字段仍然可以使用标签"-," 生成。

结构字段标签及其含义示例:

// Field appears in JSON as key "myName".
Field int `json:"myName"`

// Field appears in JSON as key "myName" and
// the field is omitted from the object if its value is empty,
// as defined above.
Field int `json:"myName,omitempty"`

// Field appears in JSON as key "Field" (the default), but
// the field is skipped if empty.
// Note the leading comma.
Field int `json:",omitempty"`

// Field is ignored by this package.
Field int `json:"-"`

// Field appears in JSON as key "-".
Field int `json:"-,"`

"string" 选项表示字段以 JSON 格式存储在 JSON-encoded 字符串中。它仅适用于字符串、浮点、整数或布尔类型的字段。在与JavaScript 程序通信时,有时会使用这种额外的编码级别:

Int64String int64 `json:",string"`

如果键名是仅由 Unicode 字母、数字和 ASCII 标点符号组成的非空字符串,引号、反斜杠和逗号除外。

匿名结构字段通常被编组,就好像它们的内部导出字段是外部结构中的字段一样,受制于下一段所述修改的通常的 Go 可见性规则。在其 JSON 标记中给出名称的匿名结构字段被视为具有该名称,而不是匿名的。接口类型的匿名结构字段被视为以该类型作为其名称,而不是匿名的。

在决定编组或解组哪个字段时,针对 JSON 修改了结构字段的 Go 可见性规则。如果同一级别有多个字段,并且该级别嵌套最少(因此将是通常的 Go 规则选择的嵌套级别),则适用以下额外规则:

1) 在这些字段中,如果有 JSON-tagged,则仅考虑标记字段,即使有多个未标记字段否则会发生冲突。

2)如果恰好有一个字段(根据第一条规则标记或未标记),则选择该字段。

3) 否则有多个字段,全部忽略;没有错误发生。

匿名结构字段的处理是 Go 1.1 中的新函数。在 Go 1.1 之前,匿名结构字段被忽略。要在当前版本和早期版本中强制忽略匿名结构字段,请为该字段提供 "-" 的 JSON 标记。

映射值编码为 JSON 对象。映射的键类型必须是字符串、整数类型或实现编码 TextMarshaler 映射键通过应用以下规则进行排序并用作 JSON 对象键,受上述字符串值说明的 UTF-8 强制:

- keys of any string type are used directly
- encoding.TextMarshalers are marshaled
- integer keys are converted to strings

指针值编码为指向的值。 nil 指针编码为空 JSON 值。

接口值编码为接口中包含的值。一个 nil 接口值编码为空 JSON 值。

通道、复数和函数值不能用 JSON 编码。尝试编码这样的值会导致 Marshal 返回 UnsupportedTypeError

JSON 不能表示循环数据结构并且 Marshal 不处理它们。将循环结构传递给 Marshal 将导致错误。

例子:

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

func main() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors []string
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
	}
	b, err := json.Marshal(group)
	if err != nil {
		fmt.Println("error:", err)
	}
	os.Stdout.Write(b)
}

输出:

{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}

相关用法


注:本文由纯净天空筛选整理自golang.google.cn大神的英文原创作品 Marshal。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。