GO 언어의 type method 작성법 (instance receiver와 pointer receiver의 차이)

in golang •  7 years ago 

GO 언어의 type method 작성법 (instance receiver와 pointer receiver의 차이)

개요

다음 내용이 궁금했다.

  • 인스턴스 리시버와 포인터 리시버 모두 '.'(도트)로 접근 가능한가?
    • C++에서는 인스턴스의 메소드는 '.' (도트)로 포인터의 메소드는 '->' (화살표)로 접근한다. GO 언어에서도 이런 차이가 있는지 궁금했다.
  • 인스턴스 리시버를 사용하면 메소드 호출 때마다 객체가 복사/생성되는가?
    • 함수 호출할 때 인자가 복사/생성되는 것처럼 리시버도 같은 방식으로 처리되는지 궁금했다.

테스트 코드 && 결과

테스트 코드

  1 //
  2 // test-code to check
  3 //  - can both instance-method and pointer-method are called by '.' ?
  4 //  - what is the 'this' address in both methods (same or diff) ?
  5 //
  6 package main
  7
  8 import "fmt"
  9
 10 type MyTypeA int
 11 type MyTypeB int
 12
 13 func (m MyTypeA) String() string {
 14   s := fmt.Sprintf("MyTypeA( val=%d, addr=%p )", int(m), &m)
 15   return s
 16 }
 17
 18 func (m MyTypeA) say() {
 19   fmt.Println("Hey A World,", m)
 20 }
 21
 22 func (m *MyTypeB) String() string {
 23   s := fmt.Sprintf("MyTypeB( val=%d, addr=%p )", int(*m), m)
 24   return s
 25 }
 26
 27 func (m *MyTypeB) say() {
 28   fmt.Println("Hey B World,", m)
 29 }
 30
 31 func main() {
 32   a := MyTypeA(10)
 33   b := MyTypeB(11)
 34   fmt.Printf("&a=%p, type(a)= %T, val(a)= %v\n", &a, a, a)
 35   fmt.Printf("&b=%p, type(b)= %T, val(b)= %v\n", &b, b, &b)
 36
 37   a.say()
 38   b.say()
 39 }

결과

$ go build test-code.go
$ ./test-code
&a=0xc4200140b0, type(a)= main.MyTypeA, val(a)= MyTypeA( val=10, addr=0xc4200140d8 )
&b=0xc4200140b8, type(b)= main.MyTypeB, val(b)= MyTypeB( val=11, addr=0xc4200140b8 )
Hey A World, MyTypeA( val=10, addr=0xc420014120 )
Hey B World, MyTypeB( val=11, addr=0xc4200140b8 )

결론

  • 인스턴스 리시버와 포인터 리시버 모두 '.'(도트)로 접근 가능한가?
    • 리시버 타입에 상관 없이 '.'(도트)로 접근한다.
  • 인스턴스 리시버를 사용하면 메소드 호출 때마다 객체가 복사/생성되는가?
    • 인스턴스 리시버를 쓰면 메소드를 호출할 때마다 리시버 인스턴스가 복사/생성된다.
    • 포인터 리시버를 쓰면 리시버 인스턴스가 복사/생성되지 않는다 (있던 것을 그대로 재사용한다).
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!