2017-06-07 6 views
0

ネストされた構造体をマーシャリングしようとしています。非機能の例を参照してくださいhere(私はGoの遊び場で "計算"と "かなり"をインポートすることはできませんが、テストロジックを再作成して出力を貼り付けました)。Go:JSONマーシャリングのネスト構造体。外部フィールドを間違って省略します。

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} 

基本的に、私はGoogle Compute Engine API client libからインスタンス構造体を埋め込む構造体、のCreateInstanceを、持っています。 CreateInstanceには、JSONタグがないExactNameとNoCleanupの2つのboolフィールドもあります。

CreateInstanceをマーシャリングしようとすると、ExactNameとNoCleanupが省略され、trueまたはfalseになります。その型を埋め込むことによって、あなたはもちろん、出力にあなたのCreateInstance構造体のフィールドのいずれかを行っていないcompute.InstanceからごCreateInstanceMarshalJSON方法を、与える本質的にあるよう

+0

ここは、遊び場の近似です。https://play.golang.org/p/9R9Yo8IemD期待どおりに動作します。 MarshalIndentはエラーを返しますか? –

+0

良い近似。いいえ、MashalIndentはエラーを返しません。 –

+0

したがって、私は現在、* CreateInstanceを渡しています。私はそれを逆参照すると、それは動作します。 –

答えて

2

compute.Instanceは、json.Marshalerです。

のように、あなたは、あなた自身のMarshalJSON方法を定義し、デフォルトのJSONの出力を使用する新しいタイプに手動でInstanceまたは再割り当て、それをマーシャリングしようとしますが、APIは、内部MarshalJSON動作に依存することができる可能性が現在または将来のバージョンとの互換性が保証されていません。

jsonマーシャリングの埋め込みタイプは、このような混乱しやすいバグを作成するのが非常に簡単なので、避けることをお勧めします。私は別の方法でそれらを構成しようとします。

+0

ありがとう!残念ながら、JSON設定スキーマをユーザーに公開したいので、「異なる方法で作成する」ことは少し難しいです。内部compute.Instanceはネストされたオブジェクトを必要とするため、埋め込みは内部compute.InstanceインスタンスまたはJSON config内のポインタよりも優れています。 –

関連する問題