2016-08-15 27 views
1

ここでGolangに新しく、他のアプリケーションの1つが消費するJSONオブジェクトに変換する構造体を取得しようとしています。私は私が仕事を知っているパーツを表示するには、オブジェクトの「アクセス」の部分に残っているStructをGolangのJSONに変換する

"access": { 
     "STOCK": "1", 
     "FOREX": "1", 
     "WEBFOREX": "1", 
     "WEBSTOCK": "1" 
    }, 
"subscription_group_dates": { 
     "32": { 
      "START_DATE": 1464753600, 
      "END_DATE": 1472616000 
      }, 
     "42": { 
      "START_DATE": 1470024000, 
      "END_DATE": 1472616000 
      } 
    } 

予想される応答は以下のようになります

...。簡潔さのために他のすべては省略されています。私にとって厳しい部分は、ゴランの構造体の入れ子の性質を扱うことです...次の構造体はうまくいくと思いますが、構文についてはわかりません。

SubscriptionGroupDatesタイプでは... map [string]構造体を使用し、残りを図のように埋め込むことはできますか?以下を参照してください

type UCSUserAccess struct { 
    Groups   map[string]string   `json:"groups"` 
    Access   map[string]string   `json:"access"` 
    IsExpert  string      `json:"isExpert"` 
    SubscriptionGroupDates map[string]struct { 
     GroupID struct { 
      StartDate map[string]int `START_DATE` 
      EndDate map[string]int `END_DATE` 
      } 
    } `json:"subscription_group_dates"` 
} 

さらに、私はインポートセクションに "time"ライブラリをインポートしました。日付を時間オブジェクトとして宣言するために、それをどのように使用しますか? (代わりに、マップの[文字列] INT)

おかげ

MarshalUnmarshal時間、この作業サンプルコードのよう

答えて

1

1-あなたが使用することができる:

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
    "strconv" 
    "time" 
) 

type UCSUserAccess struct { 
    Groups     map[string]string `json:"groups"` 
    Access     map[string]string `json:"access"` 
    IsExpert    string   `json:"isExpert"` 
    SubscriptionGroupDates map[string]struct { 
     StartDate Time `json:"START_DATE"` 
     EndDate Time `json:"END_DATE"` 
    } `json:"subscription_group_dates"` 
} 

type Time time.Time 

func (t Time) MarshalJSON() ([]byte, error) { 
    data := []byte(fmt.Sprint(time.Time(t).UTC().Unix())) 
    return data, nil 
} 
func (t *Time) UnmarshalJSON(data []byte) error { 
    i, e := strconv.ParseInt(string(data), 10, 64) 
    *t = Time(time.Unix(i, 0).UTC()) 
    return e 
} 
func (t Time) String() string { 
    return time.Time(t).UTC().String() 
} 

func main() { 
    str := `{ 
"access": { 
     "STOCK": "1", 
     "FOREX": "1", 
     "WEBFOREX": "1", 
     "WEBSTOCK": "1" 
    }, 
"subscription_group_dates": { 
     "32": { 
      "START_DATE": 1464753600, 
      "END_DATE": 1472616000 
      }, 
     "42": { 
      "START_DATE": 1470024000, 
      "END_DATE": 1472616000 
      } 
    } 
    }` 
    var d UCSUserAccess 
    err := json.Unmarshal([]byte(str), &d) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(d) 

    fmt.Println() 
    body, err := json.Marshal(d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(body)) 
} 

2-あなたはMarshalを使用することができますこの簡略化された作業サンプルコードのように、Unmarshal時間です。

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
    "strconv" 
    "time" 
) 

type UCSUserAccess struct { 
    StartDate Time `json:"START_DATE"` 
} 

type Time time.Time 

func (t Time) MarshalJSON() ([]byte, error) { 
    data := []byte(fmt.Sprint(time.Time(t).UTC().Unix())) 
    return data, nil 
} 
func (t *Time) UnmarshalJSON(data []byte) error { 
    i, e := strconv.ParseInt(string(data), 10, 64) 
    *t = Time(time.Unix(i, 0).UTC()) 
    return e 
} 
func (t Time) String() string { 
    return time.Time(t).UTC().String() 
} 

func main() { 
    str := `{ 
      "START_DATE": 1464753600 
    }` 
    var d UCSUserAccess 
    err := json.Unmarshal([]byte(str), &d) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(d) 

    fmt.Println() 
    body, err := json.Marshal(d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(body)) 
} 

3 - また、あなたは、このワーキングサンプルコードのように、時間int64を使用することがあります。

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
    "time" 
) 

type GroupID struct { 
    StartDate int64 `json:"START_DATE"` 
    EndDate int64 `json:"END_DATE"` 
} 

func (t *GroupID) Start() time.Time { 
    return time.Unix(t.StartDate, 0) 
} 
func (t *GroupID) End() time.Time { 
    return time.Unix(t.EndDate, 0) 
} 

type UCSUserAccess struct { 
    Access     map[string]string `json:"access"` 
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"` 
} 

func main() { 
    str := `{ 
"access": { 
     "STOCK": "1", 
     "FOREX": "1", 
     "WEBFOREX": "1", 
     "WEBSTOCK": "1" 
    }, 
"subscription_group_dates": { 
     "32": { 
      "START_DATE": 1464753600, 
      "END_DATE": 1472616000 
      }, 
     "42": { 
      "START_DATE": 1470024000, 
      "END_DATE": 1472616000 
      } 
    } 
    }` 
    var d UCSUserAccess 
    err := json.Unmarshal([]byte(str), &d) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(d) 
    gID := d.SubscriptionGroupDates["32"] 
    fmt.Println(gID.Start()) 

    fmt.Println() 
    body, err := json.Marshal(d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(body)) 
} 

4 - あなたはこの作業のサンプルコードのように、受信機の方法でInt64を使用することがあります。

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
    "time" 
) 

type Int64 int64 
type GroupID struct { 
    StartDate Int64 `json:"START_DATE"` 
    EndDate Int64 `json:"END_DATE"` 
} 

func (t *Int64) Time() time.Time { 
    return time.Unix(int64(*t), 0).UTC() 
} 

type UCSUserAccess struct { 
    Access     map[string]string `json:"access"` 
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"` 
} 

func main() { 
    str := `{ 
"access": { 
     "STOCK": "1", 
     "FOREX": "1", 
     "WEBFOREX": "1", 
     "WEBSTOCK": "1" 
    }, 
"subscription_group_dates": { 
     "32": { 
      "START_DATE": 1464753600, 
      "END_DATE": 1472616000 
      }, 
     "42": { 
      "START_DATE": 1470024000, 
      "END_DATE": 1472616000 
      } 
    } 
    }` 
    var d UCSUserAccess 
    err := json.Unmarshal([]byte(str), &d) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(d) 
    gID := d.SubscriptionGroupDates["32"] 
    fmt.Println(gID.StartDate.Time()) 

    fmt.Println() 
    body, err := json.Marshal(d) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println(string(body)) 
} 
+0

@ rick-masonこれは役立ちます。 –

4

あなたの構造は少しばかりです。 SubscriptionGroupDatesは、具体的には構造体への文字列のマップであり、構造体自体は文字列からintへのマップか、2つのintフィールドを持つ静的構造体のいずれかです。あなたは、ネストされた構造体秒を持っている、と彼らはint型であるべき時にあなたの日付をマップとして指定されています

type UCSUserAccess struct { 
    Groups     map[string]string `json:"groups"` 
    Access     map[string]string `json:"access"` 
    IsExpert    string    `json:"isExpert"` 
    SubscriptionGroupDates map[string]GroupID `json:"subscription_group_dates"` 
} 

type GroupID struct { 
    StartDate int `json:"START_DATE"` 
    EndDate int `json:"END_DATE"` 
} 

あなたが期待するように、これはJSONを与えます。例:https://play.golang.org/p/rGm7zKJypk(jsonlint.comを介して出力を実行して、必要な出力が得られることを確認してください)。

タイムスタンプに関しては、JSONのタイムスタンプはUnixのタイムスタンプとして保存されます。それらを時間内に取得するには、非マーシャリングの後、またはカスタム時刻型のjson.Unmarshallerインターフェイスを実装して、それらを自分で解析する必要があります。それを行う方法の詳細については、this answerを参照してください。

1

UnmarshalJSONメソッドとMarshalJSONメソッドを提供することで、独自の日付を簡単に作成できます。あなたは、入力を処理し、あなたが好きな方法で出力をフォーマットすることができます。

package main 

import (
    "encoding/json" 
    "fmt" 
    "strconv" 
    "strings" 
) 

type Date struct { 
    year int 
    month int 
    day int 
} 

func (t *Date) UnmarshalJSON(data []byte) (e error) { 
    trimmed := string(data) 
    trimmed = strings.TrimLeft(trimmed, "\"") 
    trimmed = strings.TrimRight(trimmed, "\"") 

    parts := strings.Split(trimmed, "-") 

    t.year, _ = strconv.Atoi(parts[0]) 
    t.month, _ = strconv.Atoi(parts[1]) 
    t.day, _ = strconv.Atoi(parts[2]) 

    return 
} 

func (t *Date) MarshalJSON() (buff []byte, e error) { 
    buff = []byte(fmt.Sprintf("\"%d-%d-%d\"", t.year, t.month, t.day)) 
    return 
} 

type Foo struct { 
    Groups map[string]string `json:"groups"` 
    Date Date    `json:"date"` 
} 

func main() { 

    f := Foo{ 
     Groups: map[string]string{ 
      "group1": "bar", 
      "group2": "baz", 
     }, 
     Date: Date{year: 2016, month: 12, day: 22}, 
    } 

    buff, _ := json.Marshal(&f) 

    fmt.Println(string(buff)) 

    json.Unmarshal(buff, &f) 

    fmt.Printf("%+v", f) 

} 
関連する問題