학교에서 포기했던 Pointer를 다시 마주칠 줄이야...
하지만 go는 어렵지 않게 Pointer를 학습할 수 있다!
먼저 프로그래밍에서 Pointer란 아는 사람은 다 아는 무서운 놈이다. 여기서 다들 방황을 시작하니까... go에서는 Pointer를 더욱 간단하게 사용할 수 있게 해주는데. Pointer를 사용할 수 있는 개발자는 시스템의 성능을 크게 기여할 수 있기 때문에 알면 큰 도움이 되는 개념이다.
package main
import (
"fmt"
)
func main() {
a := 5
b := a
fmt.Println(a, b)
}
다음 코드는
다음과 같이 출력된다. a와 b는 같은 값을 갖고 있다 생각할 수 있다. 그럼 이 데이터는 메모리적 구조에서 어떤 형태로 저장되어 있는 것일까?
package main
import (
"fmt"
)
func main() {
a := 5
b := a
fmt.Println(&a, &b)
}
go 에서는 &
를 사용하여 해당 데이터의 주소값을 확인해볼 수 있다. a와 b는 다른 주소값을 가진다 즉
다음과 같이 메모리적 구조적으로는 새로운 값을 생성하여 그냥 값만 가지고 있는 것이다. 이를 증명하기 위해서
package main
import (
"fmt"
)
func main() {
a := 5
b := a
a = 10
fmt.Println(a, b)
}
a의 값을 10으로 변경했지만
b의 값은 그대로 5인것을 확인할 수 있다. 그 이유는 a, b가 바라보는 메모리 주소가 다르기 때문이다.
그럼 이제 같은 주소를 바라보게 하면 어떻게 될까?
package main
import (
"fmt"
)
func main() {
a := 5
b := &a
fmt.Println(&a, b)
}
&
를 사용하여 b에 a의 주소값을 복사하도록 코드를 작성했다. 그리고 코드를 실행해보면
둘다 동일한 주소값을 갖고 있는 것을 확인할 수 있다. 그럼 이제 a의 값을 아까처럼 바꾸게 되면 a만 바뀔까?
package main
import (
"fmt"
)
func main() {
a := 5
b := &a
a = 10
fmt.Println(a, *b)
}
주소 값을 가지고 있는 변수는 *
를 사용하여 데이터 값을 불러올 수 있다.
코드를 실행하면 a와 b 둘다 10으로 변경된 것을 확인할 수 있다.
그 이유는 다음과 같이 이전에 메모리에 새로운 데이터를 넣어둔 형태가 아닌 같은 주소를 바라보고 있기 때문에 a의 값이 변경되었을 때 b의 값이 함께 변경되는 것이다.
만약 b의 값을 바꿔 본다면?
package main
import (
"fmt"
)
func main() {
a := 5
b := &a
*b = 20
fmt.Println(a, *b)
}
다음 코드를 실행하면
다음 결과를 확인해 볼수 있다.
일반적인 프로그래밍을 할땐 사용하지 않을 수 있겠지만 만약 더 작은 메모리에 프로그래밍을 해야하거나 규모가 큰 프로그램을 더욱 최적화 해야할 경우 메모리를 잘 다뤄주어야 하는데 go는 다음과 같이 간단하게 메모리를 다룰 수 있도록 도와준다. 하지만 주소값을 같이 공유하는 만큼 값을 변경할 때 신경을 써줘야하는 것도 잊지 않고 사용해야 한다는 점을 잊지 말자!