문자열 메서드의 포인터 수신기와 값 수신기
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!