Go では、カスタム Time タイプ エイリアスを印刷するときに予期しない出力が発生することがあります。動作を理解するには、問題をさらに詳しく分析する必要があります。
次のコードを考えてみましょう:
<code class="go">package main import ( "encoding/json" "fmt" "strings" "time" ) type Time time.Time func (st *Time) UnmarshalJSON(b []byte) error { s := strings.Trim(string(b), "\"") t, err := time.Parse(time.RFC3339, fmt.Sprintf("%s%s", s, "Z")) if err != nil { return fmt.Errorf("parse time: %w", err) } *st = Time(t) return nil } type User struct { Name string TS Time } const data = `{id: 3, name: "Name", ts: "2021-05-21T03:10:20.958450"}` func main() { user := new(User) json.Unmarshal([]byte(data), &user) fmt.Printf("%v\n", user) }</code>
このコードを実行すると、予期される出力はフォーマットされた時間です。
&{Name 2021-05-21 03:10:20.95845 +0000 UTC}
のような値ですが、実際の出力は次のようになります。
&{Name {958450000 63757163420 <nil>}}
Time 型のエイリアスが一致しないため、矛盾が生じます。 fmt.Stringer を実装すると、デフォルトの書式設定ロジックが引き継がれます。このロジックは、中括弧で囲まれた基になる time.Time 値のフィールドを出力します。
これを解決するには、time.Time.String にデリゲートする Time 型の String メソッドを実装します。 。これにより、目的の形式の出力が有効になります。
<code class="go">func (t Time) String() string { return time.Time(t).String() }</code>
別のオプションは、Time タイプに time.Time を埋め込むことです。これにより、String メソッドとその他のメソッド (Marshal* を含む) が自動的にプロモートされます。
<code class="go">type Time struct { time.Time } func (st *Time) UnmarshalJSON(b []byte) error { // ... unchanged ... st.Time = t // simple assignment without type conversion // ... unchanged ... }</code>
JSON を解析するときは、文字列を使用した手動解析を避けてください。代わりに、適切なデコードのために json.Unmarshal を使用してください。さらに、time.ParseInLocation:
<code class="go">func (st *Time) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } t, err := time.ParseInLocation("2006-01-02T15:04:05", s, time.UTC) if err != nil { return err } // ... unchanged ... }</code>
以上がGo でカスタムの Time 型エイリアスを印刷すると予期しない出力が生成されるのはなぜですか?また、それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。