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

Patricia Arquette
Lepaskan: 2024-10-30 15:18:42
asal
328 orang telah melayarinya

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>
Salin selepas log masuk

Apabila menjalankan kod ini, output yang dijangkakan ialah Masa yang diformatkan nilai, serupa dengan:

&{Name 2021-05-21 03:10:20.95845 +0000 UTC}
Salin selepas log masuk

Walau bagaimanapun, output sebenar muncul sebagai:

&{Name {958450000 63757163420 <nil>}}
Salin selepas log masuk

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!