go 언어를 좀 더 알아 가다 보면 C 언어와 동일하게 헷깔리는 것이 포인터가 되겠습니다. 


다음 소스의 결과를 아시는 분은 포인터와 비 포인터의 구분을 정확하게 이해 하시는 분이고 


그렇지 않은 분들은 이 부분에 대한 심화 학습이 필요하다고 판단됩니다. ^^


package main


import "fmt"


type R struct {

   id    int

   name string

}


type P struct {

   id    int

   name string

}


func ( r R ) print() {

    fmt.Println( r.id , r.name )

}


func ( r R ) set( v int ) {

    r.id = v

}


func ( r R ) set_str( s string ) {

    r.name = s

}


func ( r *P ) print() {

    fmt.Println( r.id , r.name )

}


func ( r *P ) set( v int) {

    r.id = v

}


func ( r *P ) set_str( s string ) {

    r.name = s

}


func main() {

   

   A := R{id:3,name:"three"}

   A.print()

   

   B := P{id:4,name:"four"}

   B.print()


   A.set( 5 )

   A.set_str( "hello" )

   A.print()

   

   B.set( 5 )

   B.set_str( "hello" )

   B.print()

   


이걸 실행하면 어떤 결과가 나올까요?


실행 결과는 다음과 같습니다. 


3 three

4 four

3 three

5 hello


A 는 구조체 멤버 함수 에서 어떤값을 수정해도 변경되지 않은듯 합니다. 
B 는 구조체 멤버 함수 에서 처리된 값이 적용되고 있습니다. 

왜 그럴까요?

멤버 함수의 앞에 구조체를 선언할때 * 연산자를 사용하면 해당 함수를 호출할때 
구조체 자체의 주소값을 대입하기 때문에 해당 값을 수정이 가능합니다. 

만약 *연산자를 사용하지 않은 R 구조체 멤버 함수는 원래 값을 그대로 두고 
복사한 값을 사용하기 때문에 원 데이터는 변경되지 않는 결과를 초래하게 됩니다. 

그래서 원본값을 손상시키지 않고 임시적인 작업을 하고 싶다면 * 를 안쓰는 것이 좋은데

결국 이런 경우는 대부분 복사의 시간이 걸리고 메모리 먹고 등등 

실질적인 사용에서는 그리 권장하지 않는 방법이죠

그래서 구조체 멤버 함수는 무조건 * 붙이는 구조 실용적인 방법이죠..

결론은 구조체 멤버 함수의 구조체 선언부에는 * 을 붙이자! 가 결론되겠습니다. 

    func ( r *P ) print() {
             :
    }