golang pointer 주는 혼란을 정리해보자(feat. 그림)

gyeongseon·2023년 5월 7일
0

golang

목록 보기
1/1

서론

니콜라스와 함께 무료로 Go 강의 봤습니다.

관심생겨서 다시 공부하는 중에 Pointer가 혼란스러워서 정리합니다.

💡 니콜라스는 언어를 무료로 질 높은 강의를 제공해주는 유튜버입니다. 개발자라면 필요한 정보도 영상으로 자주 만듭니다. 관심 있는 분들은 아래 링크 참고하세요.

쉽고 빠른 Go 시작하기 – 노마드 코더 Nomad Coders

💡 간단하고 빠르게 정리 한 번 하고 싶으면 아래 참고하세요.

예제로 배우는 Go 프로그래밍

본론

우선 코드를 먼저 봅시다.

package main

import (
	"fmt"
)

type Bulletin struct {
	Content string
}

// 값 타입 리시버
func (b Bulletin) Print() {
	fmt.Println(b.Content)
}

// 값 타입 리시버
func (b Bulletin) Update(value string) {
	b.Content = value
}

// 포인터 타입 리시버
func (b *Bulletin) PrintByPointer() {
	fmt.Println(b.Content)
}

// 포인터 타입 리시버
func (b *Bulletin) UpdateByPointer(value string) {
	b.Content = value
}

func main() {
	b := Bulletin{} 
	b.Content = "포인터는 인간을 화나게 만든다"
	b.Print()
	b.Update("아니 포인터는 쉽다") // 1. 업데이트 왜 안됨?!
	b.Print()

	bbp := &Bulletin{}
	bbp.Content = "포인터는 인간을 화나게 만든다"
	bbp.PrintByPointer()
	bbp.UpdateByPointer("그래도 메모리는 절약하게 할 것이다.") // 2. 업데이트 된다 !!
	bbp.PrintByPointer()

}
💡 앞으로 등장하는 M: Memory C: Copy 라는 의미로 사용했습니다.

( 저는 포인터를 글로만 이해를 하려고 하다보니까 머리가 나쁜건지 이해가 제대로 안되서 그림으로 설명하려고 합니다.)

1. 업데이트 왜 안됨 ?!


내가 이해하기 힘들었던건 코드를 순서대로 보는 점도 있었다.
그런데 pointer 컨셉을 이해하기 위해선 순서보다 메모리랑 친해지길 권장한다.

결론은 값타입 리시버는 값을 전달인자(인자, 파라미터)처럼 한 번 주고 끝나는 것이다.

그렇다면 이걸 조금 메모리랑 친하게 보려면 그림이 어떻게 될까 !?

이렇게 되지 않을까 생각했다. Update 경우는 주소에 복사해서 한 번 사용하고 바로 쓰레기통에다가 버리는 것이다.

Update를 통해서 필드를 변경해도 이건 어차피 쓰레통으로
Print는 책상위에 있는 걸 가져다가 계속 보여주는 것이다.

2. 업데이트 왜 된다 !!

사실 1번이 이해가 갔다면 2번은 굳이 안들어도 된다.

이렇게 되는 것이지 않을까 예상한다.

결론

말하고 싶은 점은 Pointer가 메모리 관점에서 생각하면 이해가 편하다는 것입니다. 그리고 golang을 익숙해지기 위해선 메모리구조와 친해져야 할 것 같았습니다. (오픈소스 사알짝 봤는데 포인터때문에 코드 읽기가 어려운 경우가 있었음.)

끝으로
<< value or pointer receiver >>
적절히 선택해서 사용합시다.

정확하고 더 좋은 배움을 받고 싶으면 아래 참고하세요. 공식적으로 지원하는 학습?! 뭐 그런겁니다.
A Tour of Go - Choosing a value or pointer receiver
A Tour of Go - Pointer receivers

profile
경선 :)

0개의 댓글