Go를 배워보자 4일차 - 포인터

0

Go

목록 보기
4/12

포인터 (Pointer)

1. 포인터의 선언

포인터 변수는 주소를 받아, 주소로 변수를 제어하는 기능이다.

pointer가 남아있는 언어가 별로 없는데 golang은 포인터를 지원한다.

이는 굉장히 강력한 기능이고 golang에 있어서 큰 장점 중 하나라고 생각한다.

포인터에는 타입과 에스테리스크(*)가 필요하다.

var 포인터변수 *포인터타입 = &변수

일반 변수 선언에서 *를 만 추가해서 사용하면 된다.

또한, 변수의 주소를 주소싶을 때는 &를 사용하면 된다.

package main

import "fmt"

func main() {
	var intValue int = 10
	var pIntValue *int = &intValue
	fmt.Print(*pIntValue) // 10
}

단축 선언을 사용하여 더 간단하게 포인터를 선언할 수도 있다.

package main

import "fmt"

func main() {
	value := 10
	pValue := &value
	fmt.Print(*pValue) // 10
}

c/c++과 마찬가지로 포인터에 에스테리스크(*)를 붙임으로서 값에 접근할 수 있다.

이번에는 값을 변경해보자

package main

import "fmt"

func main() {
	value := 10
	pValue := &value
	fmt.Println(*pValue) // 10
	*pValue = 20
	fmt.Println(value) // 20
}

2. 함수에서 포인터 사용하기

함수의 매개변수는 pass by value이다. 즉, 매개변수는 새로운 저장공간을 받고 거기에 값을 복사하는 것이지, 입력 받은 변수 자체를 일컫는게 아니다.

그냥 쌍둥이가 있다고 보면 된다.

그러므로 함수에서 아무리 매개변수로 받은 값을 변경해봤자 의미가 없다.

그러나 포인터를 이용하면 값을 바꿀 수 있다. 실제로 c/c++에서 많이 사용하는 기법으로, 반환형은 void 형 함수이지만 입력으로 구조체 포인터를 받아 값을 채워주는 방법이 있다.

package main

import "fmt"

func main() {
	value := 10
	add20(&value)
	fmt.Print(value) // 20
}

func add20(input *int) {
	*input = 20
}

다음과 같이 포인터 변수를 함수로 받아서 값을 변경해줄 수 있다.

또한, 반환값으로 포인터를 내보낼 수 있다.

package main

import "fmt"

func main() {
	value := stringProcess()
	fmt.Print(*value) // hello world
}

func stringProcess() *string {
	value := "hello world"
	return &value
}

재밌는 것은 함수안의 지역변수의 경우 스코프( 지역 변수가 살아있는 범위 ) 함수임에도 불구하고 리턴되었을 때 사라지지 않는다.

특정 프로그래밍 언어에서는 함수가 종료되면 그 블럭 안에 있는 변수들을 모두 죽이는 특성이 있다.

golang역시도 마찬가지이지만, 재밌는 것은 pointing하고 있는 것들은 지역 변수라 할 지라도 죽이지 않는다는 것이다.

즉, 함수가 종료된 지역 변수라도 포인팅하고 있는 것들이 있다면 변수가 사라지 않는 것이다.

0개의 댓글