Go에서 사용자 정의 Time 유형 별칭을 인쇄하면 예상치 못한 출력이 생성되는 이유는 무엇이며 어떻게 수정할 수 있나요?

Patricia Arquette
풀어 주다: 2024-10-30 15:18:42
원래의
333명이 탐색했습니다.

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

Time.Time 유형 별칭을 인쇄할 때 예기치 않은 출력이 발생함

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>}}
로그인 후 복사

잘못된 출력 설명

시간 유형 별칭이 그렇지 않기 때문에 불일치가 발생합니다. 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을 포함하는 것입니다. 이렇게 하면 문자열 메서드와 기타 메서드(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을 구문 분석할 때 문자열을 사용하여 수동으로 구문 분석하지 마세요.Trim; 대신 적절한 디코딩을 위해 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!