>백엔드 개발 >Golang >포인터 대신 개체를 사용하여 포인터 수신기로 Go 메서드를 호출할 수 있는 이유는 무엇입니까?

포인터 대신 개체를 사용하여 포인터 수신기로 Go 메서드를 호출할 수 있는 이유는 무엇입니까?

DDD
DDD원래의
2024-12-28 11:41:21722검색

Why Can I Call a Go Method with a Pointer Receiver Using an Object Instead of a Pointer?

객체를 사용하여 포인터용 메서드 호출

Go에서는 포인터 수신기용 메서드를 호출하는 것이 가능합니다. 포인터 대신 개체입니다. 이는 이상해 보일 수 있지만 Go 사양에 따라 허용됩니다.

다음 코드를 고려하세요.

package main

import "math"

type Vertex struct {
    X, Y float64
}

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

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func main() {
    v := Vertex{3, 4}
    v.Scale(10) // v is not a pointer to a Vertex object
    fmt.Println(v.Abs())
}

이 예에서 v는 Vertex 유형의 객체이고 Scale은 Vertex에 대한 포인터를 위한 메서드입니다. 그런데 v에 포인터를 전달하는 대신 v.Scale(10)을 직접 호출합니다.

왜 오류가 아닌가요? 대답은 메서드 호출에 대한 Go 사양에 정의된 규칙에 있습니다.

If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

이 규칙은 호출되는 값이 주소 지정이 가능한 경우(즉, 지역 변수 또는 포인터인 경우) 다음을 호출한다고 명시합니다. 해당 메서드는 해당 주소에서 메서드를 호출하는 것과 동일합니다. 이 경우 v는 지역 변수이므로 v.Scale(10)은 마치 (&v).Scale(10)을 대신 작성한 것처럼 해석됩니다.

이러한 편의 덕분에 더 깔끔하고 간결하게 작성할 수 있습니다. 메서드를 호출하기 전에 개체에 대한 포인터를 명시적으로 생성할 필요 없이 코드를 작성할 필요가 없습니다. 그러나 이는 포인터 수신기가 있는 메서드에만 작동한다는 점에 유의하는 것이 중요합니다. 값 수신자가 있는 메서드의 경우 개체에 포인터를 전달하는 것은 허용되지 않습니다.

위 내용은 포인터 대신 개체를 사용하여 포인터 수신기로 Go 메서드를 호출할 수 있는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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