Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah mencetak alias jenis Masa tersuai dalam Go menghasilkan output yang tidak dijangka dan bagaimanakah ia boleh diperbetulkan?

Mengapakah mencetak alias jenis Masa tersuai dalam Go menghasilkan output yang tidak dijangka dan bagaimanakah ia boleh diperbetulkan?

Patricia Arquette
Patricia Arquetteasal
2024-10-30 15:18:42321semak imbas

Why does printing a custom Time type alias in Go produce unexpected output, and how can it be corrected?

Output Tidak Dijangka Semasa Mencetak Masa. Alias ​​Jenis Masa

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.

Memahami Isu

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>}}

Menjelaskan Output Salah

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.

Membetulkan Output

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>

Penyelesaian Alternatif

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>

Pertimbangan Tambahan

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn