🔥 메서드와 포인터 Indirection - 2
235자
3분
Go 언어에서는 메서드가 포인터 리시버를 가질 때 값이나 포인터 모두 리시버로 받을 수 있답니다. 반대로, 함수가 값 인자를 받을 때는 해당 타입의 값만 전달할 수 있죠.
예를 들어, 다음과 같이 Vertex
타입의 값 v
가 있다고 해볼까요?
var v Vertex fmt.Println(AbsFunc(v)) // OK fmt.Println(AbsFunc(&v)) // 컴파일 에러!
go
AbsFunc
함수는 Vertex
타입의 값을 인자로 받기 때문에, v
를 직접 전달하는 것은 가능하지만 &v
와 같이 포인터를 전달하면 컴파일 에러가 발생합니다.
반면에, 값 리시버를 가진 메서드는 호출 시 값이나 포인터 모두 리시버로 사용할 수 있답니다.
var v Vertex fmt.Println(v.Abs()) // OK p := &v fmt.Println(p.Abs()) // OK
go
이 경우, p.Abs()
메서드 호출은 (*p).Abs()
로 해석됩니다.
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { // 값 리시버를 가진 Abs 메서드 return math.Sqrt(v.X*v.X + v.Y*v.Y) } func AbsFunc(v Vertex) float64 { // Vertex 타입의 값을 인자로 받는 AbsFunc 함수 return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := Vertex{3, 4} fmt.Println(v.Abs()) // 값으로 메서드 호출 fmt.Println(AbsFunc(v)) // 값을 함수에 전달 p := &Vertex{4, 3} fmt.Println(p.Abs()) // 포인터로 메서드 호출 fmt.Println(AbsFunc(*p)) // 포인터를 역참조하여 함수에 전달 }
go
이렇게 Go 언어에서는 메서드와 함수 사이에 미묘한 차이가 있죠. 메서드는 포인터 리시버를 가질 때 값이나 포인터 모두 받을 수 있지만, 함수는 값 인자를 받을 때 해당 타입의 값만 받을 수 있답니다. 이런 차이점을 잘 이해하고 활용하면 더 유연하고 가독성 높은 코드를 작성할 수 있을 거예요!