Go: JSON 编组嵌套结构;错误地省略了外部字段
Go: JSON marshalling nested struct; incorrectly omitting outer fields
我正在尝试编组嵌套结构。请参阅非功能示例 here(我无法在 Go 游乐场中导入 "compute" 和 "pretty",但我已经重新创建了我的测试逻辑并粘贴了输出)。
package main
import (
"encoding/json"
"fmt"
"github.com/kylelemons/godebug/pretty"
compute "google.golang.org/api/compute/v1"
)
type CreateInstance struct {
compute.Instance
// Additional metadata to set for the instance.
Metadata map[string]string `json:"metadata,omitempty"`
// OAuth2 scopes to give the instance. If none are specified
// https://www.googleapis.com/auth/devstorage.read_only will be added.
Scopes []string `json:",omitempty"`
// StartupScript is the Sources path to a startup script to use in this step.
// This will be automatically mapped to the appropriate metadata key.
StartupScript string `json:",omitempty"`
// Project to create the instance in, overrides workflow Project.
Project string `json:",omitempty"`
// Zone to create the instance in, overrides workflow Zone.
Zone string `json:",omitempty"`
// Should this resource be cleaned up after the workflow?
NoCleanup bool
// Should we use the user-provided reference name as the actual resource name?
ExactName bool
// The name of the disk as known internally to Daisy.
daisyName string
}
func main() {
ci := <a *CreateInstance part of a larger data structure>
j, _ := json.MarshalIndent(ci, "", " ")
fmt.Println(string(j))
pretty.Print(ci) # Pretty prints the struct.
}
##### OUTPUT #####
{
"disks": [
{
"source": "disk"
}
],
"machineType": "${machine_type}",
"name": "${instance_name}"
}
{Instance: {CanIpForward: false,
CpuPlatform: "",
CreationTimestamp: "",
Description: "",
Disks: [{AutoDelete: false,
Boot: false,
DeviceName: "",
DiskEncryptionKey: nil,
Index: 0,
InitializeParams: nil,
Interface: "",
Kind: "",
Licenses: [],
Mode: "",
Source: "disk",
Type: "",
ForceSendFields: [],
NullFields: []}],
Id: 0,
Kind: "",
MachineType: "${machine_type}",
Metadata: nil,
Name: "${instance_name}",
NetworkInterfaces: [],
Scheduling: nil,
SelfLink: "",
ServiceAccounts: [],
Status: "",
StatusMessage: "",
Tags: nil,
Zone: "",
ServerResponse: {HTTPStatusCode: 0,
Header: {}},
ForceSendFields: [],
NullFields: []},
Metadata: {},
Scopes: [],
StartupScript: "",
Project: "",
Zone: "",
NoCleanup: false,
ExactName: false}
基本上,我有一个结构 CreateInstance,它嵌入了 Google Compute Engine API client lib 中的实例结构。 CreateInstance 还有两个没有 JSON 标签的 bool 字段,ExactName 和 NoCleanup。
当我尝试编组 CreateInstance 时,ExactName 和 NoCleanup 被忽略,无论它们是真还是假。
A compute.Instance
是一个 json.Marshaler
,因此通过嵌入该类型,您实际上是在为 CreateInstance
提供 compute.Instance
中的 MarshalJSON
方法,这当然不会输出 CreateInstance
结构中的任何字段。
您可以定义自己的 MarshalJSON
方法,并尝试手动编组 Instance
或将其重新分配给将使用默认 json 输出的新类型,但是API 可能依赖于内部 MarshalJSON
行为,因此不能保证当前或未来版本兼容。
最好避免 json 封送处理的嵌入类型,因为这样很容易产生令人困惑的错误。我会尝试以不同的方式编写它们。
我正在尝试编组嵌套结构。请参阅非功能示例 here(我无法在 Go 游乐场中导入 "compute" 和 "pretty",但我已经重新创建了我的测试逻辑并粘贴了输出)。
package main
import (
"encoding/json"
"fmt"
"github.com/kylelemons/godebug/pretty"
compute "google.golang.org/api/compute/v1"
)
type CreateInstance struct {
compute.Instance
// Additional metadata to set for the instance.
Metadata map[string]string `json:"metadata,omitempty"`
// OAuth2 scopes to give the instance. If none are specified
// https://www.googleapis.com/auth/devstorage.read_only will be added.
Scopes []string `json:",omitempty"`
// StartupScript is the Sources path to a startup script to use in this step.
// This will be automatically mapped to the appropriate metadata key.
StartupScript string `json:",omitempty"`
// Project to create the instance in, overrides workflow Project.
Project string `json:",omitempty"`
// Zone to create the instance in, overrides workflow Zone.
Zone string `json:",omitempty"`
// Should this resource be cleaned up after the workflow?
NoCleanup bool
// Should we use the user-provided reference name as the actual resource name?
ExactName bool
// The name of the disk as known internally to Daisy.
daisyName string
}
func main() {
ci := <a *CreateInstance part of a larger data structure>
j, _ := json.MarshalIndent(ci, "", " ")
fmt.Println(string(j))
pretty.Print(ci) # Pretty prints the struct.
}
##### OUTPUT #####
{
"disks": [
{
"source": "disk"
}
],
"machineType": "${machine_type}",
"name": "${instance_name}"
}
{Instance: {CanIpForward: false,
CpuPlatform: "",
CreationTimestamp: "",
Description: "",
Disks: [{AutoDelete: false,
Boot: false,
DeviceName: "",
DiskEncryptionKey: nil,
Index: 0,
InitializeParams: nil,
Interface: "",
Kind: "",
Licenses: [],
Mode: "",
Source: "disk",
Type: "",
ForceSendFields: [],
NullFields: []}],
Id: 0,
Kind: "",
MachineType: "${machine_type}",
Metadata: nil,
Name: "${instance_name}",
NetworkInterfaces: [],
Scheduling: nil,
SelfLink: "",
ServiceAccounts: [],
Status: "",
StatusMessage: "",
Tags: nil,
Zone: "",
ServerResponse: {HTTPStatusCode: 0,
Header: {}},
ForceSendFields: [],
NullFields: []},
Metadata: {},
Scopes: [],
StartupScript: "",
Project: "",
Zone: "",
NoCleanup: false,
ExactName: false}
基本上,我有一个结构 CreateInstance,它嵌入了 Google Compute Engine API client lib 中的实例结构。 CreateInstance 还有两个没有 JSON 标签的 bool 字段,ExactName 和 NoCleanup。
当我尝试编组 CreateInstance 时,ExactName 和 NoCleanup 被忽略,无论它们是真还是假。
A compute.Instance
是一个 json.Marshaler
,因此通过嵌入该类型,您实际上是在为 CreateInstance
提供 compute.Instance
中的 MarshalJSON
方法,这当然不会输出 CreateInstance
结构中的任何字段。
您可以定义自己的 MarshalJSON
方法,并尝试手动编组 Instance
或将其重新分配给将使用默认 json 输出的新类型,但是API 可能依赖于内部 MarshalJSON
行为,因此不能保证当前或未来版本兼容。
最好避免 json 封送处理的嵌入类型,因为这样很容易产生令人困惑的错误。我会尝试以不同的方式编写它们。