포인터는 어떠한 값의 메모리 주소를 저장합니다.
Go 언어 포인터는 개념 자체는 같지만 다른 언어와는 약간 다른 특징을 가지고 있으니 이에 대해 중점적으로 살펴보도록 하겠습니다.
Go 언어 포인터
포인터 자체에 대한 개념은 상세하게 설명하지 않겠습니다.
Go 언어에서도 포인터는 메모리 주소(혹은 위치)를 참조하는 참조 타입의 변수입니다.
C 계열 언어의 스타일과 비슷하게 &를 붙여 메모리 주소를 구하고, *를 사용하여 실제 값을 구할 수 있습니다.
var a int = 42
var p *int = &a
변수의 타입 앞에 *를 붙여서 포인터 변수임을 꼭 명시해주어야 합니다.
Go 언어 포인터의 zero value는 nil입니다.
Go 언어 포인터의 특징
Go 언어는 포인터에 대한 기본적인 개념은 동일하게 지원합니다.
하지만, C 계열 언어에서 지원하는 포인터 연산은 지원하지 않습니다.
nil 포인터라는 개념이 존재하는데 어떠한 값도 가리키지 않는 포인터를 의미합니다.
이 nil 포인터를 사용하게 되면 nil 값을 참조하기 때문에 런타임 에러가 발생합니다.
따라서, 포인터를 사용하기 전에 nil 여부를 꼭 확인해주어야 합니다.
Go 언어는 가비지 컬렉션을 지원합니다.
이에 포인터는 가비지 컬렉션의 감시를 받게 됩니다.
만약, 어떠한 데이터가 포인터를 통해 계속 참조되고 있으면 해당 데이터에 대한 메모리를 해제하지 않습니다.
따라서 이를 방지하기 위해 사용이 끝난 포인터는 nil로 꼭 설정해주어야 메모리 누수를 방지할 수 있습니다.
Go 언어 포인터 예시
간단한 예시를 살펴보고 마치도록 하겠습니다.
이전에 만들었던 프로젝트에 새로운 파일(예를 들어 pointer.go)을 만들어서 작성해봅시다.
func updateValue(val *int) {
*val = 100
}
func main() {
x := 50
updateValue(&x)
fmt.Println(x) // 100 출력
}
main 함수에 존재하는 x 변수의 메모리 주소를 받아서 직접 값을 변경할 수 있는 것을 이해하면 됩니다.
다음 글에서 알아볼 내용
Go 언어 구조체