Heim  >  Artikel  >  Backend-Entwicklung  >  Warum führt das Drucken eines benutzerdefinierten Time-Typ-Alias ​​in Go zu einer unerwarteten Ausgabe und wie kann dies korrigiert werden?

Warum führt das Drucken eines benutzerdefinierten Time-Typ-Alias ​​in Go zu einer unerwarteten Ausgabe und wie kann dies korrigiert werden?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-30 15:18:42321Durchsuche

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

Unerwartete Ausgabe beim Drucken eines Time.Time-Typ-Alias

In Go kann es beim Drucken eines benutzerdefinierten Time-Typ-Alias ​​zu einer unerwarteten Ausgabe kommen. Um das Verhalten zu verstehen, muss das Problem weiter analysiert werden.

Das Problem verstehen

Bedenken Sie den folgenden Code:

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

Beim Ausführen dieses Codes ist die erwartete Ausgabe eine formatierte Zeit Wert, ähnlich wie:

&{Name 2021-05-21 03:10:20.95845 +0000 UTC}

Die tatsächliche Ausgabe sieht jedoch wie folgt aus:

&{Name {958450000 63757163420 <nil>}}

Erklärung der falschen Ausgabe

Die Diskrepanz entsteht, weil der Zeittyp-Alias ​​dies nicht tut Implementieren Sie fmt.Stringer, wodurch die Standardformatierungslogik übernommen wird. Diese Logik gibt die zugrunde liegenden time.Time-Wertfelder in geschweiften Klammern aus.

Korrigieren der Ausgabe

Um dieses Problem zu beheben, implementieren Sie eine String-Methode im Time-Typ, die an time.Time.String delegiert . Dies ermöglicht die gewünschte formatierte Ausgabe:

<code class="go">func (t Time) String() string {
    return time.Time(t).String()
}</code>

Alternative Lösung

Eine weitere Möglichkeit besteht darin, time.Time in den Time-Typ einzubetten. Dies fördert automatisch die String-Methode und andere Methoden (einschließlich 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>

Zusätzliche Überlegungen

Vermeiden Sie beim Parsen von JSON das manuelle Parsen mit Strings.Trim; Verwenden Sie stattdessen json.Unmarshal für die ordnungsgemäße Dekodierung. Vereinfachen Sie außerdem die Zeitanalyse mit 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>

Das obige ist der detaillierte Inhalt vonWarum führt das Drucken eines benutzerdefinierten Time-Typ-Alias ​​in Go zu einer unerwarteten Ausgabe und wie kann dies korrigiert werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn