지금까지 언어를 배우면서 메서드와 함수를 거의 혼용하여 사용하고 있었습니다. Go를 배우며 함수와 메서드의 차이에 대하여 확실하게 잡게 되어 다행이라고 생각합니다.
Go에서는 메서드를 어떻게 선언하는지 알아보겠습니다.
목차
메서드란?
메서드의 함수 표현식
메서드란?
메서드라는 것은 함수를 호출하는 객체가 있는 경우를 메서드라고 합니다.
Go언어에서는 class 혹은 object가 없기에 type를 통하여 메서드를 선언할 수 있습니다.
Go언어에서 정의한 메서드는 '사용자 정의 타입 값에 호출할 수 있는 특별한 함수'라고 이야기하고 있습니다.
메서드와 함수의 차이
다른 언어에서는 메서드와 함수의 형식이 크게 다르지 않았습니다. 하지만 Go 언어는 메서드는 형식부터가 다릅니다.
메서드 예시
func(리시버) 메서드 명 (매개변수) 반환 값 {
메서드 내용
}
함수와는 다르게 메서드는 리시버를 필요로 합니다. 리시버는 사용자 정의 타입 값이 들어가는 자리가 됩니다.
메서드 생성
type money uint
func (dollar money) checkEnough(check money) bool {
result := dollar >= check
fmt.Println(result)
return result
}
func (dollar *money) deposit(addAmount money) money {
*dollar = *dollar + addAmount
return *dollar
}
func (dollar *money) withdraw(subAmount money) money {
*dollar = *dollar - subAmount
return *dollar
}
위와 같은 방식으로 local type을 리시버 타입으로 가지는 메서드를 생성할 수 있습니다.
Pointer에서 설명드렸듯 Go언어는 값에 의한 호출이 기본 방식이므로 리시버 변수의 값을 변경하기 위하여 포인터로 지정하여야 합니다.
생성한 type을 리시브로 사용하기 때문에 구조체도 메서드를 만들 수 있습니다.
메서드 사용
위의 코드로 생성된 메서드를 사용하는 예시 코드는 아래와 같습니다.
func main(){
var myDollar money = 1000
fmt.Println(myDollar) // 1000
myDollar.checkEnough(1500) // false
myDollar.deposit(600)
fmt.Println(myDollar) // 1600
myDollar.checkEnough(1500) // true
myDollar.withdraw(1500)
fmt.Println(myDollar) // 100
}
메서드의 함수 표현식
생성한 메서드를 변수에 할당하여 함수의 매개변수로 전달할 수 있습니다.
메서드의 함수 표현식은 메서드의 리시버를 첫 번째 매개변수로 전달하는 함수입니다.
depositFn := (*money).deposit
withdrawFn := (*money).withdraw
checkEnough := (money).checkEnough
var myDollar money = 1000
fmt.Println(myDollar) // 1000
checkEnough(myDollar,1500) // false
depositFn(&myDollar, 600)
fmt.Println(myDollar) // 1600
myDollar.checkEnough(1500) // true
withdrawFn(&myDollar, 1500)
fmt.Println(myDollar) // 100
위의 설명에서 생성하였던 메서드를 위의 코드와 같이 변수에 지정할 수 있습니다.
함수 표현식으로 바꾸었을 때 사용법은 리시버를 첫 번째 매개변수로 전달하여야 합니다.
아직 다양한 활용을 해본 것이 아니기에 어떠한 방식으로 사용하는 것이 유용한지는 모르겠습니다.
그렇기 때문에 최대한 다양한 표현방식을 알아두고 필요에 따라 사용하는 것을 추천드립니다.
'Go language' 카테고리의 다른 글
[Go] 고루틴 이해하기 (뮤텍스, 데드락) (0) | 2023.08.27 |
---|---|
[Go] 인터페이스 (어댑터) (0) | 2023.08.26 |
[Go] Pointer이해하기 (call by value 주의사항) (0) | 2023.08.25 |
[Go] 구조체와 임베디드 구조체 (0) | 2023.08.24 |
[Go] Go언어 배열 (정적, 동적, slice, append, range) (0) | 2023.08.23 |