Go의 메소드 호출에서 *t와 t의 뉘앙스 이해
Go에서 포인터('*') 사용 메소드 수신자는 메소드의 기능에 상당한 영향을 미칠 수 있습니다. 이 차이점은 다음 코드 조각에서 강조 표시됩니다.
package main import "fmt" type TT struct { a int b float32 c string } func (t *TT) String() string { return fmt.Sprintf("%+v", *t) // Original implementation } // func (t *TT) String() string { // return fmt.Sprintf("%+v", t) // Altered implementation // } func main() { tt := &TT{3, 4, "5"} fmt.Printf(tt.String()) }
String() 메서드의 원래 구현에서는 t가 nil인 경우 nil 포인터에 액세스하는 위험을 방지하는 포인터 수신기(*TT)를 사용합니다. . 그러나 포인터가 아닌 수신기(TT)를 사용하도록 String() 메서드를 수정하면 데드 루프가 발생합니다.
데드 루프의 이유:
핵심 이 동작을 이해하는 것은 Go의 fmt 패키지가 fmt.Stringer 인터페이스를 구현하는 유형(즉, 사용자 정의 String() 메소드를 제공하는 유형)을 처리하는 방법에 있습니다. *TT 유형의 값을 인쇄할 때 fmt.String()은 먼저 *TT가 유효한 String() 메소드를 구현하는지 확인합니다. 그렇다면 해당 메서드를 호출하여 값의 문자열 표현을 얻습니다. 이는 *TT의 메소드 세트에 String() 메소드가 포함되어 있으므로 *TT에 포인터 수신자가 있는 경우에 잘 작동합니다.
그러나 String()의 수신자가 포인터가 아닌 유형으로 변경되는 경우(즉, TT) 문제가 발생합니다. 이 경우 TT의 메소드 세트에는 String() 메소드가 포함되어 있습니다. 이는 fmt.String()이 t(TT의 인스턴스) 값을 인쇄하려고 시도할 때 t.String()을 호출한다는 것을 의미합니다. Turn은 자신을 다시 호출하여 무한 재귀로 이어집니다.
데드 루프 방지:
데드 루프를 방지하려면 유형 변환이라는 기술을 사용할 수 있습니다. type 키워드를 사용하여 새 유형을 생성하고 fmt.String()에 전달된 값을 변환하면 무한 재귀를 피할 수 있습니다.
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
이 경우 새 유형(TT2)에는 메서드가 없습니다. , 따라서 fmt.String()이 변환된 값을 인쇄하려고 시도할 때 변환된 유형에 대해 String() 메서드를 호출하지 않습니다.
결론:
이해 fmt.String() 함수를 사용하여 사용자 정의 유형을 인쇄할 때 잠재적인 함정을 피하려면 메서드 수신기에서 *t와 t의 차이가 중요합니다. 수신기 유형을 신중하게 고려하고 필요한 경우 유형 변환을 사용하면 데드 루프를 방지하고 메서드 호출이 올바르게 작동하도록 보장할 수 있습니다.
위 내용은 Go에서 `*t`와 `t`를 메서드 수신자로 사용하는 것의 의미는 무엇이며, `fmt.String()`을 사용할 때 데드 루프를 어떻게 방지할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!