>백엔드 개발 >Golang >값 기반 개체를 전달할 때 fmt.Println이 스트링거 인터페이스의 문자열 메서드를 호출하지 않는 이유는 무엇입니까?

값 기반 개체를 전달할 때 fmt.Println이 스트링거 인터페이스의 문자열 메서드를 호출하지 않는 이유는 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-12-06 19:35:15493검색

Why Doesn't fmt.Println Invoke My Stringer Interface's String Method When Passing a Value-Based Object?

Println과의 스트링거 인터페이스 혼동: 값 기반 객체와 포인터 기반 객체 이해

질문:

객체가 Stringer 인터페이스를 구현하는 시나리오에서 왜 객체가 값 기반인 경우 fmt.Println을 사용할 때 객체의 String 메서드가 호출됩니까?

코드 예:

다음 Go 코드를 고려하세요.

type Car struct {
    year int
    make string
}

func (c *Car) String() string {
    return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}

func main() {
    myCar := Car{year: 1996, make: "Toyota"}
    fmt.Println(myCar)
}

myCar가 포인터이면 String 메서드가 예상대로 호출됩니다. 그러나 myCar가 값이면 기본 Go 형식이 대신 사용됩니다.

답변:

이 동작의 이유는 Go 인터페이스 작동 방식에 있습니다. 인터페이스를 구현하는 유형(이 경우 Stringer)을 지정하면 Go는 해당 유형이 인터페이스의 정확한 유형일 것으로 기대합니다. Car 유형의 값을 fmt.Println에 전달하면 암시적으로 인터페이스{}로 변환되며 인터페이스{} 유형 시스템에는 Car 유형이 없습니다. 대신 *Car 유형입니다(Car에 대한 포인터).

fmt.Println 함수는 유형 스위치를 사용하여 유형에 따라 값을 인쇄하는 방법을 결정합니다. Stringer 인터페이스의 경우 값이 String 메서드를 구현하는지 확인합니다. Car(값 기반)는 문자열을 구현하지 않으므로 기본 형식이 사용됩니다. 그러나 myCar.String()을 명시적으로 호출하면 컴파일러는 이를 올바른 *Car 유형을 갖고 원하는 형식 지정 방법을 호출하는 (&myCar).String()으로 자동 변환합니다.

객체의 형식이 유형에 관계없이 원하는 대로 지정되는 경우 두 가지 옵션이 있습니다.

  1. 자동차에 문자열 구현 (값 기반): 이를 위해서는 값 수신자에서 작동하는 Car에 대한 별도의 String 메소드를 생성해야 하며, 이로 인해 불필요한 객체 복사가 발생합니다.
  2. 항상 fmt.Println에 포인터를 전달합니다. fmt.Println(&myCar)을 사용하면 전달된 값에 올바른 *Car 유형이 있는지 확인하고 String 메소드가 다음과 같이 호출됩니다. 예상됩니다.

위 내용은 값 기반 개체를 전달할 때 fmt.Println이 스트링거 인터페이스의 문자열 메서드를 호출하지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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