>  기사  >  백엔드 개발  >  Go 포인터: 값 대 포인터 수신기 - 그게 중요합니까?

Go 포인터: 값 대 포인터 수신기 - 그게 중요합니까?

Barbara Streisand
Barbara Streisand원래의
2024-11-07 17:51:02914검색

Go Pointers: Value vs. Pointer Receivers - Does it Matter?

Go 포인터: 값 및 포인터 수신기 자세히 살펴보기

Go에서 포인터는 메모리를 효과적으로 관리하고 재사용 가능한 항목을 생성하는 데 중요한 역할을 합니다. 데이터 구조. 초보자는 특히 C/C와 같은 언어와 다르기 때문에 포인터 개념에 어려움을 겪는 경우가 많습니다. 이 글의 목적은 Go 포인터의 미묘한 차이를 명확히 하고 일반적인 오해를 해결하는 것입니다.

Go Tour #52에서 빌린 아래 코드 조각을 고려하세요.

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())
}

여기서 구조체를 정의합니다. 정점 및 정점의 절대값을 계산하는 메서드 Abs입니다. Abs의 수신자 v는 Vertex에 대한 포인터입니다. 이는 Abs가 꼭짓점에 대한 포인터에서 작동하여 원래 꼭짓점을 수정할 수 있음을 의미합니다.

이제 코드를 약간 수정해 보겠습니다.

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

흥미롭게도 이 수정으로 인해 같은 결과. 질문이 생깁니다. *Vertex 또는 Vertex를 Abs의 수신자로 사용하는 것 사이에 차이가 있습니까?

답은 Go의 두 가지 기본 규칙에 있습니다.

  1. 값 및 포인터 수신기 변환: Go를 사용하면 값 수신기가 있는 메서드에서 포인터 수신기가 있는 메서드를 파생할 수 있습니다. 따라서 func(v Vertex) Abs() float64는 자동으로 추가 구현을 생성합니다.

    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가 포인터가 아닌데도 v.Abs()가 계속 작동하는 이유를 설명합니다. .

  2. 자동 주소 가져오기: Go에서는 변수의 주소를 자동으로 가져올 수 있습니다. 이는 포인터 수신기 없이 수정된 코드에서 v.Abs()를 호출할 때 다음과 동일하다는 것을 의미합니다.

    vp := &v
    vp.Abs()

    따라서 함수는 명시적으로 &를 사용하는지 여부에 관계없이 여전히 정점에 대한 포인터를 받습니다. .

위 내용은 Go 포인터: 값 대 포인터 수신기 - 그게 중요합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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