문자열 방식의 포인터 수신기가 Go에서 데드 루프로 이어지는 이유는 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2024-11-23 21:15:20
원래의
748명이 탐색했습니다.

Why Does a Pointer Receiver in String Method Lead to a Dead Loop in Go?

문자열 메서드의 포인터 수신기와 값 수신기

Go에서는 String() 메서드를 사용하여 사용자 정의 문자열 표현을 제어합니다. 유형. String() 메서드를 정의할 때 포인터 수신자와 값 수신자의 차이점을 이해하는 것이 중요합니다.

다음 코드를 고려하세요.

type TT struct {
    a int
    b float32
    c string
}

func (t *TT) String() string {
    return fmt.Sprintf("%+v", *t)
}
로그인 후 복사

이 코드에서 String( ) 메소드에는 포인터 수신기가 있습니다. 이는 TT 값에 대한 포인터에서 작동함을 의미합니다. tt.String()을 호출하면 (*tt).String()이 효과적으로 호출됩니다.

이제 String() 메서드를 다음과 같이 변경하는 것이 좋습니다.

func (t *TT) String() string {
    return fmt.Sprintf("%+v", t)
}
로그인 후 복사

이 변경으로 인해 포인터가 제거됩니다. String() 메서드가 TT 유형의 값에 대해 작동하도록 만듭니다.

왜 이로 인해 죽은 결과가 발생합니까? loop?

fmt 패키지는 인쇄되는 값이 Stringer 인터페이스를 구현하는지(또는 String() 메서드가 있는지) 확인합니다. 그렇다면 해당 메서드를 호출하여 문자열 표현을 얻습니다. 그러나 이 경우에는 String() 메서드에 대한 포인터 수신기가 있습니다.

tt.String()을 호출하면 fmt 패키지는 *TT 유형의 값을 전달합니다. 그러나 String() 메서드에는 TT 유형의 값이 필요합니다. 이러한 불일치로 인해 fmt 패키지가 String() 메서드를 다시 호출하고, 이 메서드가 다시 호출되는 식으로 무한 루프가 발생합니다.

예방/보호

이 데드 루프를 방지하려면 String() 메서드의 수신자 유형이 fmt 패키지에 전달된 값의 유형과 일치하는지 확인하세요. 어떤 이유로 동일한 수신자 유형을 사용해야 하는 경우 type 키워드를 사용하여 새 유형을 생성하고 fmt.Sprintf를 호출하기 전에 값을 새 유형으로 변환할 수 있습니다.

func (t TT) String() string {
    type TT2 TT
    return fmt.Sprintf("%+v", TT2(t))
}
로그인 후 복사

새 유형을 생성하여 유형을 사용하면 기본 유형에서 모든 메소드를 제거하여 효과적으로 주기를 중단하고 fmt.Sprintf를 안전하게 호출할 수 있습니다.

위 내용은 문자열 방식의 포인터 수신기가 Go에서 데드 루프로 이어지는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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