[Go] 12. 메서드

2024. 1. 21. 13:35Go

반응형

메서드는 함수와 달리 func 오른쪽에 소괄호로 리시버를 받습니다.
리시버는 type키워드로 선언된 모든 로컬 타입들을 입력받을 수 있습니다. (= type으로 선언된 별칭들이나 구조체)

  • 메서드를 잘 활용하면 데이터와 관련 기능을 묶어 응집도를 높일 수 있습니다.
func (r Receiver) methodName() int {
	return r.width * r.height
}

아래 예제를 확인해보면, 기존의 함수와 메서드의 차이점을 알 수 있습니다.

package main  

import "fmt"  

type account struct {  
  balance int  
}  

func withdrawFunc(a *account, amount int) {  
  a.balance -= amount  
}  

func (a *account) withdrawMethod(amount int) {  
  a.balance -= amount  
}  

func main() {  
  a := &account{1000}  
  withdrawFunc(a, 30)  
  fmt.Printf("잔액: %d\n", a.balance)  

  a.withdrawMethod(50)  
  fmt.Printf("잔액: %d\n", a.balance)  
}
잔액: 970
잔액: 920

포인터 함수로 선언된 a를 함수를 이용하는 방법과 메서드를 이용하는 방법에 대해 알아보았습니다.

메서드는 리시버타입인 *account에 속해있고, 그렇게 때문에 a.withdrawMethod(50) 같은 방식으로 사용할 수 있습니다.

모든 로컬 타입들은 리시버가 될 수 있습니다.
만약, int와 같은 타입에도 메서드를 활용하고 싶다면 별칭타입을 선언해두고 메서드를 선언하면 됩니다.

int 타입에 별칭을 정의한 후 아래와 같이 메서드를 설정할 수 있습니다.

type myInt int  

func (a myInt) add(b int) int {  
  return int(a) + b  
}
func main() {  
  var a myInt = 10  
  fmt.Println(a.add(5))  
  var b = 10  
  fmt.Println(myInt(b).add(5))  
}

포인터 메서드, 값타입 메서드

리시버로 이용하는 타입을 포인터를 이용하여 메서드 수행결과를 전달할 수도 있고,
또는 값으로 넘겨주되 리턴타입으로 반환하는 방법이 있습니다.

package main  

import "fmt"  

type account struct {  
  balance int  
}  

func (a *account) withdrawPointer(amount int) {  
  a.balance -= amount  
}  

func (a account) withdrawRetureValue(amount int) account {  
  a.balance -= amount  
  return a  
}  

func main() {  
  a := account{1000}  

  (&a).withdrawPointer(50)  
  fmt.Printf("a 잔액: %d\n", a.balance)  

  fmt.Println("------------")  

  a2 := a.withdrawRetureValue(30)  
  fmt.Printf("a 잔액: %d\n", a.balance)  
  fmt.Printf("a2 잔액: %d\n", a2.balance)  
}
a 잔액: 950
------------
a 잔액: 950
a2 잔액: 920

리시버를 포인터로 설정하는 withdrawPointer 메서드는 수행한 후, 원본인 a의 값에 영향을 줍니다

그러나, 값으로 리시버를 받으면서 리턴하는 withdrawRetureValue 메서드는, 리시버값을 새로 메모리에 복사한 후 메서드 수행결과를 리턴하기 때문에, a2에는 우리가 원하는대로 920이 출력되지만, 기존 원본값인 a에는 영향을 주지 않습니다.

이러한 성질을 잘 유의하여 상황에 맞게 메서드를 선언해야합니다.

728x90
반응형

'Go' 카테고리의 다른 글

[Go] 14. 함수 고급편  (0) 2024.02.04
[Go] 13. 인터페이스  (0) 2024.01.21
[Go] 10. 패키지  (0) 2024.01.20
[Go] 09. 문자열  (0) 2024.01.18
[Go] 08. 포인터  (0) 2024.01.18