Go:JSON编组嵌套结构;错误地忽略外部字段
我正在尝试封送嵌套结构。请看一个不起作用的示例(我无法在Go游乐场中导入“compute”和“pretty”,但我已经重新创建了测试逻辑并粘贴了输出)Go:JSON编组嵌套结构;错误地忽略外部字段,json,go,marshalling,Json,Go,Marshalling,我正在尝试封送嵌套结构。请看一个不起作用的示例(我无法在Go游乐场中导入“compute”和“pretty”,但我已经重新创建了测试逻辑并粘贴了输出) 主程序包 进口( “编码/json” “fmt” “github.com/kylelemons/godebug/pretty” compute“google.golang.org/api/compute/v1” ) 类型CreateInstance结构{ 计算实例 //要为实例设置的其他元数据。 元数据映射[string]string`json:
主程序包
进口(
“编码/json”
“fmt”
“github.com/kylelemons/godebug/pretty”
compute“google.golang.org/api/compute/v1”
)
类型CreateInstance结构{
计算实例
//要为实例设置的其他元数据。
元数据映射[string]string`json:“元数据,省略为空”`
//OAuth2作用域来提供实例。如果未指定
// https://www.googleapis.com/auth/devstorage.read_only 将添加。
作用域[]字符串`json:,省略为空“`
//StartupScript是此步骤中使用的启动脚本的源路径。
//这将自动映射到相应的元数据密钥。
StartupScript字符串`json:,省略为空'`
//要在中创建实例的项目将覆盖工作流项目。
项目字符串`json:“,省略为空”`
//要在其中创建实例的区域,将覆盖工作流区域。
区域字符串`json:“,省略为空”`
//是否应在工作流结束后清理此资源?
夜光布尔
//我们应该使用用户提供的引用名称作为实际的资源名称吗?
正名布尔
//Daisy内部已知的磁盘名称。
daisyName字符串
}
func main(){
ci:=.CreateInstance还有两个没有JSON标记的bool字段,ExactName和NoCleanup
当我试图封送CreateInstance时,ExactName和NoCleanup被省略,不管它们是真是假。acompute.Instance
是一个json.Marshaler
,因此通过嵌入该类型,本质上就是从compute.Instance
中提供MarshalJSON
方法,这当然是我的sn不会输出CreateInstance
结构中的任何字段
您可以定义自己的MarshalJSON
方法,并尝试手动封送实例
,或将其重新分配给将使用默认json输出的新类型,但API可能依赖内部MarshalJSON
行为,因此不能保证与当前或未来版本兼容
最好避免嵌入json封送处理的类型,因为这样很容易产生令人困惑的错误。我会尝试以不同的方式组合它们。acompute.Instance
是一个json.Marshaler
,因此通过嵌入该类型,您实质上是为CreateInstance
提供了封送jsoncompute.Instance
中的方法,它当然不会输出CreateInstance
结构中的任何字段
您可以定义自己的MarshalJSON
方法,并尝试手动封送实例
,或将其重新分配给将使用默认json输出的新类型,但API可能依赖内部MarshalJSON
行为,因此不能保证与当前或未来版本兼容
最好避免为json封送嵌入类型,因为这样很容易产生令人困惑的错误。我会尝试以不同的方式组合它们。这里有一个近似值:它按预期工作。封送缩进是否返回错误?近似值很好。不,MashalIndent不会返回错误。因此,我很抱歉当前正在传递一个*CreateInstance。当我撤销它时,它会工作。不,这更像是正在发生的事情:这里有一个近似值:它按预期工作。MarshalIndent是否返回错误?很好的近似值。不,MashalIndent不会返回错误。因此,我当前正在传递一个*CreateInstance。当我撤销它时,它会工作。不,这是is更像是正在发生的事情:嘿,谢谢!不幸的是,试图“以不同的方式编写它们”这有点困难,因为我们想向用户公开JSON配置模式。嵌入比JSON配置中的内部compute.Instance实例或指针更好,因为内部compute.Instance需要一个嵌套对象。嘿,谢谢!不幸的是,尝试“以不同的方式组合它们”这有点困难,因为我们想向用户公开JSON配置模式。嵌入比JSON配置中的内部compute.Instance实例或指针更好,因为内部compute.Instance需要嵌套对象。
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}