>  기사  >  백엔드 개발  >  충돌하는 `String()` 메서드가 있는 유형을 포함할 때 Go의 `fmt.Println`이 예기치 않은 출력을 생성하는 이유는 무엇입니까?

충돌하는 `String()` 메서드가 있는 유형을 포함할 때 Go의 `fmt.Println`이 예기치 않은 출력을 생성하는 이유는 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-11-24 09:08:10295검색

Why Does Go's `fmt.Println` Produce Unexpected Output When Embedding Types with Conflicting `String()` Methods?

임베디드 유형의 예기치 않은 String() 메소드 동작

Go에서 임베딩을 사용하면 유형이 자체 구조 내에 다른 유형의 필드와 메소드를 포함할 수 있습니다. 그러나 여러 내장 유형이 동일한 이름(예: String())을 가진 메서드를 정의하는 경우 특정 시나리오에서 예기치 않은 동작이 발생할 수 있습니다.

다음 코드를 고려하세요.

type Engineer struct {
    Person
    TaxPayer
    Specialization string
}

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("name: %s, age: %d", p.Name, p.Age)
}

type TaxPayer struct {
    TaxBracket int
}

func (t TaxPayer) String() string {
    return fmt.Sprintf("%d", t.TaxBracket)
}

func main() {
    engineer := Engineer{
        Person: Person{
            Name: "John Doe",
            Age:  35,
        },
        TaxPayer: TaxPayer{3},
        Specialization: "Construction",
    }
    fmt.Println(engineer)
}

이 코드가 실행되면 다음과 같은 출력이 생성됩니다.

{name: John Doe, age: 35 3 Construction}

Person 및 내장 유형 내에 여러 String() 메서드가 정의되어 있으므로 이 결과는 혼란스러워 보일 수 있습니다. 납세자. 그러나 모호성은 다음 규칙에 따라 해결됩니다.

  • 여러 내장 유형이 String() 메서드를 정의하는 경우 이는 "불법 선택기"로 간주됩니다. 즉, 직접 액세스할 수 없습니다(엔지니어 호출을 통해). .String() 등).
  • 결과적으로 String() 메서드는 포함 유형(엔지니어)으로 승격되지 않으므로 기본 형식(인쇄 필드 값)이 사용됩니다.
  • 그러나 fmt 패키지는 Engineer 값에 대한 기본 문자열 표현을 생성하려고 시도할 때 값이 fmt.Stringer 인터페이스(String() 메소드가 있음)를 구현하는지 확인합니다. .
  • Person 유형은 fmt.Stringer를 구현하므로 해당 String() 메소드가 호출되어 필드(이름 및 문자열)의 문자열 표현을 생성합니다. age).

Person.String() 메서드 또는 TaxPayer.String() 메서드를 제거하면 모호성이 해결되어 나머지 String() 메서드를 기본 형식 지정에 사용할 수 있습니다.

이 동작에서 중요한 점은 포함된 유형이 단일하고 명확한 메서드가 정의된 경우에만 String() 메서드를 승격한다는 것입니다. 여러 메서드가 존재하는 경우 포함 유형에는 승격된 String() 메서드가 없으며 기본 형식이 사용됩니다.

위 내용은 충돌하는 `String()` 메서드가 있는 유형을 포함할 때 Go의 `fmt.Println`이 예기치 않은 출력을 생성하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.