카테고리 없음
Go ) 포인터
코드베어
2020. 6. 1. 09:40
Go 언어는 C, C++와 마찬가지로 메모리 주소를 표현하는 포인터를 지원한다.
- var 변수명 *자료형
var numPtr *int // 포인터형 변수를 선언하면 nil로 초기화됨
fmt.Println(numPtr) // nil
C 언어와는 달리 *(Asterisk, 애스터리스크)를 자료형 앞에 붙인다. 그리고 포인터형 변수를 선언하면 nil로 초기화된다.
※ Go 언어는 NULL 값을 nil로 사용한다. 단 C 언어에서 NULL이 정수 0으로 정의되어 있지만 Go 언어에서 nil은 숫자 0이 아니다.
빈 포인터형 변수는 바로 사용할 수 없으므로 new 함수로 메모리를 할당해야 한다.
- 포인터 변수 = new(자료형)
var numPtr *int = new(int)
fmt.Println(numPtr) // 메모리 주소가 출력됨
new 함수는 지정한 자료형의 크기에 맞는 메모리 공간을 할당한다. Go 언어는 메모리를 관리해주는 가비지 컬렉션을 지원하므로 메모리를 할당한 뒤 해제하지 않아도 된다.
포인터형 변수에 값을 대입하거나, 가져오려면 역참조(dereference)를 사용한다.
var numPtr *int = new(int) // new 함수로 공간 할당
*numPtr = 1 // 역참조로 포인터형 변수에 값을 대입
fmt.Println(*numPtr) // 1: 포인터형 변수에서 값을 가져오기
변수를 선언할 때 *를 붙이면 포인터형 변수가 되지만, 변수를 사용할 때 *를 붙이면 역참조가 된다.
일반 변수에 참조(레퍼런스)를 사용하면 포인터형 변수에 대입할 수 있다.
var num int = 1
var numPtr *int = &num // 참조로 num 변수의 메모리 주소를 구하여 numPtr 포인터 변수에 대입
변수 앞에 &를 붙이면 해당 변수의 메모리 주소를 뜻한다.
Go 언어에서는 메모리 주소를 직접 대입하거나 포인터 연산을 허용하지 않는다.
var numPtr *int = new (int)
numPtr++ // 컴파일 에러. 포인터 연산은 허용하지 않음
numPtr = 0xc0820062d0 // 컴파일 에러. 메모리 주소를 직접 대입할 수 없음
fmt.Println(numPtr)
함수에 포인터형 매개변수를 사용하면 함수 밖의 변수에 접근할 수 있다.
func hello(n *int) {
*n = 2 // 포인터 변수 n을 역참조하여 메모리에 2를 대입
}
func main() {
var n int = 1
hello(&n) // 1이 들어있는 변수 n의 메모리 주소를 hello 함수에 넘김
fmt.Println(n) // 2
}