[go] Go 언어에서 메소드의 리시버(receiver)

Go 언어는 강력한 객체 지향 프로그래밍 기능을 제공하며, 이를 통해 사용자 정의 타입에 메소드를 연결할 수 있습니다. 이러한 메소드는 리시버(receiver)라는 특별한 매개변수를 받으며, 이를 통해 메소드가 호출되는 구조체나 인터페이스 등의 타입에 접근할 수 있습니다.

리시버의 종류

Go 언어에서 메소드의 리시버는 값을 전달하는 방식에 따라 두 가지 형태로 정의할 수 있습니다.

  1. 값(receiver by value): 구조체나 값 타입을 리시버로 사용합니다. 이 경우, 메소드가 호출될 때 리시버의 복사본이 생성되며, 이를 통해 메소드 내에서 리시버의 값을 변경한다고 해도 원본 값에는 영향을 주지 않습니다.
// Point 구조체 정의
type Point struct {
    X, Y int
}

// 값을 받는 리시버를 가지는 메소드 정의
func (p Point) Print() {
    fmt.Println(p.X, p.Y)
}

// 메소드 호출
p := Point{2, 3}
p.Print() // 출력: 2 3
  1. 포인터(receiver by pointer): 포인터 타입을 리시버로 사용합니다. 이 경우, 메소드가 호출될 때 리시버의 포인터가 전달되며, 이를 통해 메소드 내에서 리시버의 값을 변경하면 원본 값에도 영향을 주게 됩니다.
// Point 구조체 정의
type Point struct {
    X, Y int
}

// 포인터를 받는 리시버를 가지는 메소드 정의
func (p *Point) Scale(factor int) {
    p.X *= factor
    p.Y *= factor
}

// 메소드 호출
p := &Point{2, 3}
p.Scale(2)
fmt.Println(p.X, p.Y) // 출력: 4 6

메소드 호출

Go 언어에서는 메소드 호출 시 리시버를 생략하거나 포인터를 사용하여 호출할 수 있습니다. 값 타입 리시버를 가진 메소드를 호출할 때는 리시버가 값으로 전달되며, 포인터 타입 리시버를 가진 메소드를 호출할 때는 리시버의 포인터가 전달됩니다.

// Point 구조체 정의
type Point struct {
    X, Y int
}

// 값을 받는 리시버를 가지는 메소드 정의
func (p Point) Print() {
    fmt.Println(p.X, p.Y)
}

// 포인터를 받는 리시버를 가지는 메소드 정의
func (p *Point) Scale(factor int) {
    p.X *= factor
    p.Y *= factor
}

// 메소드 호출
p := Point{2, 3}
p.Print() // 값 타입 리시버를 가진 메소드 호출

q := &Point{4, 5}
q.Scale(2) // 포인터 타입 리시버를 가진 메소드 호출

참고 자료