니콜라스와 함께 무료로 Go 강의 봤습니다.
관심생겨서 다시 공부하는 중에 Pointer가 혼란스러워서 정리합니다.
💡 니콜라스는 언어를 무료로 질 높은 강의를 제공해주는 유튜버입니다. 개발자라면 필요한 정보도 영상으로 자주 만듭니다. 관심 있는 분들은 아래 링크 참고하세요.쉽고 빠른 Go 시작하기 – 노마드 코더 Nomad Coders
💡 간단하고 빠르게 정리 한 번 하고 싶으면 아래 참고하세요.우선 코드를 먼저 봅시다.
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
라는 의미로 사용했습니다.
( 저는 포인터를 글로만 이해를 하려고 하다보니까 머리가 나쁜건지 이해가 제대로 안되서 그림으로 설명하려고 합니다.)
내가 이해하기 힘들었던건 코드를 순서대로 보는 점도 있었다.
그런데 pointer 컨셉을 이해하기 위해선 순서보다 메모리랑 친해지길 권장한다.
결론은 값타입 리시버는 값을 전달인자(인자, 파라미터)처럼 한 번 주고 끝나는 것이다.
그렇다면 이걸 조금 메모리랑 친하게 보려면 그림이 어떻게 될까 !?
이렇게 되지 않을까 생각했다. Update 경우는 주소에 복사해서 한 번 사용하고 바로 쓰레기통에다가 버리는 것이다.
Update를 통해서 필드를 변경해도 이건 어차피 쓰레통으로
Print는 책상위에 있는 걸 가져다가 계속 보여주는 것이다.
사실 1번이 이해가 갔다면 2번은 굳이 안들어도 된다.
이렇게 되는 것이지 않을까 예상한다.
말하고 싶은 점은 Pointer가 메모리 관점에서 생각하면 이해가 편하다는 것입니다. 그리고 golang을 익숙해지기 위해선 메모리구조와 친해져야 할 것 같았습니다. (오픈소스 사알짝 봤는데 포인터때문에 코드 읽기가 어려운 경우가 있었음.)
끝으로
<< value or pointer receiver >>
적절히 선택해서 사용합시다.
정확하고 더 좋은 배움을 받고 싶으면 아래 참고하세요. 공식적으로 지원하는 학습?! 뭐 그런겁니다.
A Tour of Go - Choosing a value or pointer receiver
A Tour of Go - Pointer receivers