Go:JSON编组嵌套结构;错误地省略外部字段

时间:2017-06-07 01:40:51

标签: json go marshalling

我试图整理嵌套结构。请参阅非功能性示例here(我无法在Go游乐场中导入"计算"和#34;漂亮"但我已经重新创建了我的测试逻辑并粘贴输出)。

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的Instance结构。 CreateInstance还有两个没有JSON标记的bool字段,ExactName和NoCleanup。

当我尝试封送CreateInstance时,省略了ExactName和NoCleanup,无论是真还是假。

1 个答案:

答案 0 :(得分:2)

compute.Instancejson.Marshaler,因此通过嵌入该类型,您实际上是从CreateInstance提供MarshalJSON compute.Instance方法,当然不会输出CreateInstance结构中的任何字段。

您可以定义自己的MarshalJSON方法,并尝试手动编组Instance或将其重新分配给将使用默认json输出的新类型,但API可能依赖于内部MarshalJSON行为,因此无法保证与当前或未来版本兼容。

最好避免嵌入json marshaling的类型,因为它很容易造成像这样的混乱错误。我会尝试以不同的方式撰写它们。