Dalam Go, seseorang mungkin menghadapi output yang tidak dijangka apabila mencetak alias jenis Masa tersuai. Memahami tingkah laku memerlukan membedah isu ini dengan lebih lanjut.
Pertimbangkan kod berikut:
<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>
Apabila menjalankan kod ini, output yang dijangkakan ialah Masa yang diformatkan nilai, serupa dengan:
&{Name 2021-05-21 03:10:20.95845 +0000 UTC}
Walau bagaimanapun, output sebenar muncul sebagai:
&{Name {958450000 63757163420 <nil>}}
Percanggahan timbul kerana alias jenis Masa tidak melaksanakan fmt.Stringer, menyebabkan logik pemformatan lalai mengambil alih. Logik ini mencetak masa yang mendasari. Medan nilai masa yang dilampirkan dalam pendakap kerinting.
Untuk menyelesaikannya, laksanakan kaedah Rentetan dalam jenis Masa yang mewakilkan kepada masa.Time.String . Ini membolehkan output berformat yang diingini:
<code class="go">func (t Time) String() string { return time.Time(t).String() }</code>
Pilihan lain ialah membenamkan masa.Masa dalam jenis Masa. Ini secara automatik mempromosikan kaedah String dan kaedah lain (termasuk 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>
Apabila menghuraikan JSON, elakkan penghuraian manual dengan rentetan.Trim; sebaliknya, gunakan json.Unmarshal untuk penyahkodan yang betul. Selain itu, mudahkan penghuraian masa menggunakan masa.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>
Atas ialah kandungan terperinci Mengapakah mencetak alias jenis Masa tersuai dalam Go menghasilkan output yang tidak dijangka dan bagaimanakah ia boleh diperbetulkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!