07 포인터

Go language course for beginners


포인터는 메모리 상에서 어떤 한 지점을 가르키는 주소 값 입니다.

Go에서의 포인터는 "uintptr" 정수형과 같은 크기를 가집니다.

어떤 변수의 주소를 가르키는 포인터를 생성하려면 변수 이름 앞에 "&"를 붙여야 합니다.

이렇게 만들어진 포인터의 타입은 "*변수타입"입니다.

Go에서의 포인터의 Zero Value는 nil입니다.

var ptr *int

var value int = 1000

ptr = &value

fmt.Println(ptr)

// 0xc000126000 (실행시마다 다르게 나올 수 있습니다)

포인터는 "*" 연산자를 사용하여 포인터가 가르키는 값을 가져올 수 있습니다.

이를 dereferencing 이라고 합니다.

"*"연산자로 포인터가 가르키는 값에 대입 하는 것을 "indirecting"이라고 합니다.

var ptr *int

var value int = 1000

ptr = &value

fmt.Println(value, *ptr) // dereferencing

*ptr = 2000 // indirecting

fmt.Println(value, *ptr)

// 1000 1000
// 2000 2000

예를 들어 함수 내부에서 외부의 값을 변경하거나 참조만 전달하고 싶은 경우에 포인터를 사용하면 됩니다.

func swap(x *int, y *int) { // int의 포인터 타입을 인자로 받는 swap 함수
    var temp int

    temp = *x
    *x = *y
    *y = temp
}

func swap2(x, y int) { // int 타입을 인자로 받는 swap2 함수
    var temp int

    temp = x
    x = y
    y = temp
}

func main() {
    var a int = 100
    var b int = 200

    fmt.Println("a = ", a, "b = ", b) // a =  100 b =  200

    swap(&a, &b) // 포인터를 전달하는 경우

    fmt.Println("a = ", a, "b = ", b) // a =  200 b =  100

    swap2(a, b) // 값을 전달하는 경우

    fmt.Println("a = ", a, "b = ", b) // a =  200 b =  100 값이 변경되지 않습니다.
}

unsafe.Pointer

주의: 여기서 다루는 내용은 Go 1 호환성 가이드라인에 의하여 보호되지 않습니다.

Go에서의 포인터는 일반적으로 Pointer arithmetic 연산이 불가능합니다.

unsafe.Pointer는 자유로운 타입을 가지는 포인터를 제공합니다.

(포인터타입)(unsafe포인터)를 이용해서 unsafe.Pointer를 다른 포인터로 변환 할 수 있습니다.

또한 unsafe.Pointer는 uintptr과 상호 변환이 가능해서 Pointer arithmetic 연산을 할 수 있습니다.

var ptr unsafe.Pointer

var value int = 1000

ptr = unsafe.Pointer(&value)

intptr := (*int)(ptr) // unsafe.Pointer를 *int타입으로 변환

fmt.Println(value, *intptr) // dereferencing

// 1000 1000

What's next?

다음 포스트에서는 메서드와 인터페이스를 살펴보겠습니다.