>백엔드 개발 >Golang >Go 포인터: 내 메서드에 값이나 포인터를 전달할 수 있는 것처럼 보이는 이유는 무엇입니까?

Go 포인터: 내 메서드에 값이나 포인터를 전달할 수 있는 것처럼 보이는 이유는 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-11-10 13:57:02778검색

 Go Pointers: Why Does It Seem Like I Can Pass Either a Value or a Pointer to My Method?

Go 포인터: 포인터 의미 이해하기

포인러는 참조를 통해 메모리 주소와 값을 조작할 수 있는 Go 프로그래밍의 기본 개념입니다. 포인터는 다른 프로그래밍 언어와 유사점을 공유하지만 Go의 포인터 의미 체계는 고유할 수 있으며 초보자에게 혼란을 야기할 수 있습니다.

다음 코드를 고려하세요.

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}

코드 조각은 Vertex 구조체를 정의하고 정점 좌표의 절대값을 계산하는 func (v *Vertex) Abs() 메서드. 메소드 수신자를 *Vertex 포인터로 선언함으로써 메소드가 Vertex 값에 대한 포인터에서 작동함을 나타냅니다.

코드를 다음과 같이 수정하면:

func (v Vertex) Abs() float64 {
    [...]
    v := &Vertex{3, 4}
}

여기서 수신자는 더 이상 포인터가 아니라 값(Vertex)이므로 동일한 결과를 얻게 됩니다. 그 이유는 두 가지입니다:

메서드 파생: Go에서는 값 수신기가 있는 메서드에서 포인터 수신기가 있는 메서드를 파생할 수 있습니다. 이는 func(v Vertex) Abs() 메소드가 추가 메소드 구현을 자동으로 생성한다는 것을 의미합니다.

func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
func (v *Vertex) Abs() float64 { return Vertex.Abs(*v) } // GENERATED METHOD

v.Abs()를 호출하면(여기서 v는 포인터가 아님) 컴파일러는 자동으로 다음을 찾습니다. 생성된 메서드를 사용합니다.

자동 주소 가져오기: Go에는 변수의 주소를 자동으로 가져오는 기능이 있습니다. 아래 코드에서

func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
func main() {
    v := Vertex{3, 4}
    v.Abs()
}

v.Abs() 표현식은 다음 코드와 동일합니다.

vp := &v
vp.Abs()

이 시나리오에서 컴파일러는 자동으로 v 변수의 주소를 가져옵니다. 그리고 이를 포인터 수신자 메서드 func(v *Vertex) Abs()에 전달합니다.

따라서 언급한 코드 수정의 경우 Abs( ) 메서드를 사용하면 Go의 포인터 의미 체계가 올바른 동작을 보장합니다. 그러나 Go에서 구조체와 같은 참조 유형으로 작업할 때는 포인터를 사용하는 것이 일반적으로 좋은 습관으로 간주됩니다.

위 내용은 Go 포인터: 내 메서드에 값이나 포인터를 전달할 수 있는 것처럼 보이는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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