language, framework, library/golang

[Go] Java 개발자의 GoLang 튜토리얼 - Method와 Receiver

사바라다 2023. 9. 26. 01:54

개요

안녕하세요. Java에서는 Class를 이용하여 코드를 캡슐화하고 OOP를 달성하는 기초로 활용합니다. 하지만 GoLang에는 클래스를 지원하지 않습니다. type struct로 커스텀 object를 만들 수는 있지만 method를 내부에 가질 수 없습니다. golang에서는 하지만, 그와 타입에 대한 method를 정의할 수 있는 방법이 별도로 있는데요. 그 방법에 대해서 알아보도록 하겠습니다.

Receiver

클래스 내부의 함수 즉, 메소드(Method)를 사용하기 위해서는 sturct type을 먼저 작성하고 Receiver 함수를 만들어주야합니다. 선언은 아래처럼할 수 있습니다.

func (r {{ReceiverType}}) {{MethodName}}({{arguments}}) { 
 // method implementation 
}

func로 처음 함수 keyword 선언을합니다. 그리고 ReceiverType으로 struct type을 지정합니다. 그리고 Method의 이름과 아규먼트를 넣습니다. 함수 구조에 (r {{ReceiverType}})만 추가해주면 되는 구조입니다.

실제로 사용은 아래처럼 할 수 있습니다.

type Vertex struct { // type struct로 구조체 선언
  X, Y float64
}

func (v Vertex) Abs() float64 { // Vertext type에 대한 Method 선언
  return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

A receiver parameter on a value type

위의 Vertext처럼 구조체(struct) 형식이 아닌 type MyFloat float64 와 같은 type 또한 Receiver를 사용할 수 있습니다. 하지만 기본 타입에는 사용할 수 없습니다.

type MyInt int

func (m MyInt) IsPositive() bool {
    return m > 0
}

위의 예제를 보면 int 타입을 MyInt로 새로운 type을 지정했습니다. 이렇게 커스텀 type을 지정한 후 Receiver를 사용할 수 있습니다. IsPositive Function을 MyInt의 Method로 선언하였습니다.

이렇게 지정한 type 및 receiver는 아래처럼 사용할 수 있습니다.

func main() {
    var i MyInt = 5
    fmt.Println(i.IsPositive()) // Output: true
}

A receiver parameter on a pointer type

포인트 Receiver로써 Method를 선언할 수 있습니다. 즉, 값을 복사하여 연산 후 반환하는 것이 아닌 내부 필드의 값을 직접 제어할 수 있다는 의미입니다. 아래의 예제를 보도록 하겠습니다.

type Person struct {
    Name string
    Age  int
}

func (p *Person) UpdateName(Name string) {
    p.Name = Name
}

func (p Person) UpdateAge(Age int) {
    p.Age = Age
}

UpdateName의 Receiver는 Person으로 pointer를 사용하였고, 그리고 UpdateAge의 Receiver는 Person으로 value를 사용하였습니다. pointer Receiver는 사용한 object의 내부 값을 바꿀 수 있지만 value Recevier는 복사해서 사용하기 때문에 실제 내부 메모리의 값은 바꿀 수 없습니다. 아래는 테스트 사용 예제입니다.

func main() {
    person := &Person{Name: "Alice", Age: 25}
    person.UpdateName("Bob")
    fmt.Println(person.Name) // Output: Bob
    person.UpdateAge(50)
    fmt.Println(person.Age) // Output: 25
}

마무리

오늘은 이렇게 Java에서 class method에 대응되는 go의 Receiver에 대해서 알아보는 시간을 가져보았습니다.

감사합니다.

참고

[1] https://go-tour-ko.appspot.com/methods/1

[2] https://blog.devgenius.io/receiver-parameter-in-go-f0c3e25b7b10