[Go] Pointer ์ฝ๊ฒ ์ดํดํด๋ณด์
๋ชฉ์ฐจ
- Pointer ๊ธฐ๋ณธ ๊ฐ๋ ์ก๊ธฐ
- Pointer ๋ฅผ ์ฌ์ฉํ๋ ์ด์
- Go ๋ ์ ๊ตณ์ด ํฌ์ธํฐ๋ฅผ ๋์ ํ์๊น?
- ๋ฒ์ธ) ์๋ฐ์ ํฌ์ธํฐ๋?
Pointer ๊ธฐ๋ณธ ๊ฐ๋ ์ก๊ธฐ
๊ทธ๋์ ํฌ์ธํฐ๊ฐ ๋ฌด์์ผ๊น? ํฌ์ธํฐ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ ์ฅํ๋ ํน๋ณํ ๋ณ์๋ฅผ ์๋ฏธํ๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฃผ์?? ์ง๊ด์ ์ผ๋ก ์ดํด๋์ง ์๋ ๋ฌธ์์ ์ซ์ ๊ฐ์ ๋ ์ฌ๋ ธ๋ค๋ฉด ์ ๋ต์ด๋ค. ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ์ปดํจํฐ์ RAM(Random Access Memory)์์ ํน์ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๊ณ ์ ํ ์์น๋ฅผ ๋ํ๋ด๋ ์ซ์๊ฐ์ ์๋ฏธํ๋ค. ๊ฐ๋ฐ์๊ฐ ์ด๋ค ๋ณ์๋ฅผ ์ ์ธํ์ฌ ๊ฐ์ ํ ๋นํ๋ฉด, ๋ณ์ ๋ฐ์ดํฐ๋ ๋ฉ๋ชจ๋ฆฌ์ ํน์ ์์น์ ํ ๋น๋ ๊ฐ์ ์ ์ฅ๋๋ค. ์ฆ ํด๋น ๋ณ์๋ ํน์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ํ ๋น๋ฐ์ ๊ฐ์ ์ ์ฅํ๋ค. ์ด ๋ฉ๋ชจ๋ฆฌ ์์น, ์ฆ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ํ๋ด๋ ๊ฒ์ด ๋ฐ๋ก ํฌ์ธํฐ๋ค! ์ฝ๋๋ก ์ดํดํด๋ณด์.
/*
- ํฌ์ธํฐ ์ ์ธ
- var ๋ณ์๋ช
*ํ์
<<< asterik ์ ๋ถ์ฌ ํฌ์ธํฐ ์ ์ธ
- int ํ์
์ ํฌ์ธํฐ
*/
var po *int
po ๋ณ์๋ ํฌ์ธํฐ๋ก ์ ์ธ๋์๋ค. ๊ทผ๋ฐ ์ด์ int ๋ฅผ ๊ณ๋ค์ธ...
๋ฉ๋ชจ๋ฆฌ ํน์ ์์น์ int ํ์ ์ ๊ฐ์ด ์ ์ฅ๋๋ฉด po ๋ก ํด๋น int ํ์ ๋ณ์๊ฐ ์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋์ง ์ ์ ์๋ค. ์๋ ์์์์ number ๋ผ๋ Int type ๋ณ์๊ฐ ๋์จ๋ค. ์ด ๋ณ์๊ฐ ์ด๋ค ๊ฐ, ์๋ฅผ ๋ค์ด 100์ ์ ์ฅํ๋ค๊ณ ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ์ ์ด๋ค ์ฃผ์์ ์ด 100์ด๋ ๊ฐ์ด ์ ์ฅ๋ ๊ฒ์ด๋ค. ์ฐ๋ฆฌ ๊ฐ๋ฐ์๋ค์ 100์ด ์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์ ์ฅ๋๋์ง ์ ๊ฒฝ์ฐ์ง ์์๋ ๋์ง๋ง, ์ปดํ์ผ๋ฌ ์ ์ฅ์์๋ ์ด ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์์์ผ ํ๋ค. ์ด ๋ po ๋ผ๋ ํฌ์ธํฐ ๋ณ์๋ฅผ ํตํด number ๋ณ์๊ฐ ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋์ง ์์๋ผ ์ ์๋ ๊ฒ์ด๋ค.
var number int
var po *int
po = &number
์ด ๋ number ๋ณ์ ์์ ๋ถ์ ampersand(&) ๋ ๋ฌด์์ ์๋ฏธํ๋๊ฐ?
& ๊ธฐํธ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฃผ์๋ฅผ ๋ช ์ํ๋ผ๋ operator ๋ก number ๋ณ์๊ฐ ์ด๋ค ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ๊ฐ์ ์ ์ฅํ๋์ง ์ ์ ์๋ค. ์ฆ &number ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์๋ฏธํ๊ธฐ์ po ํฌ์ธํฐ ๋ณ์์ ํ ๋นํ ์ ์๋ ๊ฒ์ด๋ค.
func main() {
var number int = 10
var pointer *int
pointer = &number
fmt.Println("number:", number)
fmt.Println("pointer:", pointer)
fmt.Println("*pointer:", *pointer)
fmt.Println("&number:", &number)
}
> number: 10
> pointer: 0xc000104040
> *pointer: 10
> &number: 0xc000104040
number ๋ณ์์ 10 ์ด ์ ์ฅ๋ ์์น๊ฐ `0xc000104040` ์ด๋ฏ๋ก, number ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ํ ๋น๋ฐ์ pointer ์ญ์ ๋์ผํ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ์ถ๋ ฅํ๋ค.
์ญ์ฐธ์กฐ
์ ์์ ์์ pointer ๋ณ์์ *๋ฅผ ๋ถ์ด๋ฉด 10์ด ์ถ๋ ฅ๋๋ ๊ฒ์ ํ์ธํ๋ค. pointer ๋ณ์๋ number ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๋ ํฌ์ธํฐ์ธ๋ฐ, ์ด ํฌ์ธํฐ์ asterik(*) ์ ๋ถ์ด๋ฉด number ๊ฐ์ ์ ๊ทผํ ์ ์๋ค. ์์ ์ ์ธ๋ฒ์งธ ์ถ๋ ฅ๋ฌธ์์ ํฌ์ธํฐ ๋ณ์์ asterik ์ ๋ถ์ฌ ๊ฐ(10)์ ์ ๊ทผํ ์ ์๋๊ฑธ ์ ์ ์๋ค. ์์์ ๋ณด์ฌ์ค๋ค. ๊ฐ์ ์ ๊ทผํ ์ ์๋ค๋ ๊ฑด, ์์ ๋ ๊ฐ๋ฅํ๋ค๋ ์๋ฏธ๋ค. ์๋ ์์ ๋ฅผ ํตํด ํ์ธํด๋ณด์.
func main() {
var number int
var pointer *int
number = 10
pointer = &number
fmt.Println("[before] number:", number)
// ์ญ์ฐธ์กฐ๋ก ๊ฐ ์์ ์๋
*pointer = 0
fmt.Println("*pointer:", *pointer)
fmt.Println("[after] number:", number)
}
> [before] number: 10
> *pointer: 0
> [after] number: 0
๋ถ๋ช ์ต์ด number ๋ณ์๋ 10 ์ ํ ๋น๋ฐ์ง๋ง ๋ง์ง๋ง ์ถ๋ ฅ๋ฌธ์์๋ 0 ์ ๊ฐ์ง๊ณ ์๋ค. *pointer ๋ฅผ ํตํด number ๋ณ์์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ(value of memory address) ์ ์ ๊ทผํ์ฌ ๋ค๋ฅธ ๊ฐ(0)์ ํ ๋นํ ์ ์๋ค.
Pointer ๋ฅผ ์ฌ์ฉํ๋ ์ด์
์ด์ ๊ตฌ์กฐ์ฒด์์ pointer ๋ฅผ ์ฌ์ฉํด๋ณด์.
๋ ๊ฐ ๋ฉ์๋ (editName, editNamePointer) ์ ๋ฉ์๋ ๋ก์ง์ ๊ฐ์ง๋ง ๋ฉ์๋ ์๊ทธ๋์ฒ์ ์ฐจ์ด๊ฐ ์๋ค. ์ ์๋ Item ๊ตฌ์กฐ์ฒด์ ๊ฐ์ ๋ฐ๊ณ ํ์๋ Item ๊ตฌ์กฐ์ฒด์ ํฌ์ธํฐ๋ฅผ ์ ๋ฌ๋ฐ๋๋ค. ์ด๊ฒ์ด ์ด๋ค ์ฐจ์ด๋ฅผ ๋ง๋๋์ง ์์๋ณด์.
type Item struct {
name string
}
func editName(item Item) {
item.name = "์ปคํผ"
fmt.Println("editName:", item.name)
fmt.Println(&item.name)
}
func editNamePointer(item *Item) {
item.name = "์ปคํผ"
fmt.Println("editName:", item.name)
fmt.Println(&item.name)
}
func main() {
item := Item {"์๋ฃ์"}
fmt.Println("์ถ๋ ฅ:", item.name)
fmt.Println("์ถ๋ ฅ:", &item.name)
editName(item)
fmt.Println("๊ฒฐ๊ณผ:", item.name)
// &item ์ item ๊ตฌ์กฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ -> ์ธ์๋ก ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋๊ธด๋ค.
editNamePointer(&item) // item ์ ๋ฃ์ผ๋ฉด compile Error ๋ฐ์
fmt.Println("๊ฒฐ๊ณผ:", item.name)
}
> ์ถ๋ ฅ: ์๋ฃ์
> ์ถ๋ ฅ: 0xc00009a070
> editName: ์ปคํผ
> 0xc00009a090
> ๊ฒฐ๊ณผ: ์๋ฃ์ // name ์ด ์ปคํผ๋ก ๋ณ๊ฒฝ๋์ง ์์ (์๋ณธ ์ํฅ ๋ฐ์ง ์์)
> editName: ์ปคํผ
> 0xc00009a070
> ๊ฒฐ๊ณผ: ์ปคํผ // name ์ด ์ปคํผ๋ก ๋ณ๊ฒฝ๋จ (์๋ณธ ์์ ๋จ)
// ๊ฐ ํจ์ ๋ด๋ถ์์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ถ๋ ฅํ๋ฉด ์๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ๋์ด์์์ ํ์ธํ ์ ์๋ค.
Go ๋ ๊ธฐ๋ณธ์ ์ผ๋ก Call by value ๋ฅผ ๋ฐ๋ฅด๊ธฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ณต์ฌํด์ ํจ์ ๋ด๋ถ๋ก ์ ๋ฌํ๋ค. ์ฆ ์๋ณธ ๊ฐ์ฒด๊ฐ ์๋ ๋ณต์ฌ๋ณธ์ ๋ง๋ค์ด ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก ๋๊ธฐ๋ ์ ์ด๋ค. ๋ง์ฝ ์๋ณธ์ ์์ ํ๊ณ ์ถ๋ค๋ฉด ํฌ์ธํฐ๋ฅผ ํตํด ์์ ํ ์ ์๋ค.
editNamePointer ๋ Item ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ํฌ์ธํฐ ๋ณ์ ํํ๋ก ์ ๋ฌ๋ฐ๋๋ค. ์ฆ editNamePointer() ๋ด๋ถ๋ ์ ๋ฌ๋ฐ์ ์ธ์์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ก ์ ๊ทผ ๊ฐ๋ฅํ์ฌ ์๋ณธ์ ๊ฐ์ ์์ ํ ์ ์๋ค.
๋ฐ๋ฉด editName ๋ ์ธ์๋ก ์ผ๋ฐ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ๋ฐ๋๋ฐ, ์ฌ๊ธฐ์ ์ผ๋ฐ ๊ฐ์ฒด๋ ์๋ณธ์ ๋ณต์ฌ๋ณธ์ ์๋ฏธํ๋ค. ์ฆ ๋ณต์ฌ๋ณธ์ ๊ฐ์ ์์ ํ๋๋ผ๋ ์๋ณธ์ ์ํฅ์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์ editName() ํจ์๋ฅผ escape ํ ํ์ item ๊ฐ์ฒด์ ๊ฐ์ ํ์ธํ๋ฉด ๋ณํ์ง ์์ ๊ฑธ ํ์ธํ ์ ์๋ค.
Q. editNamePointer ๋ ์ธ์๋ก ํฌ์ธํฐ ๋ณ์๋ฅผ ๋ฐ๋๋ค. ์ธ์๋ asterik(*)์ธ๋ฐ ํจ์ ํธ์ถ๋ถ์์ ๋๊ธฐ๋ ๊ฒ์ ampersand(&) ๋ค. ๊ทธ๋ผ ๋ฉ์๋ ์ ์ ํ ๋ & ํ์ ์ผ๋ก ์ธ์๋ฅผ ์ ์ํ๋ฉด ์ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ ๊น?
๋ผ๋ ์ด๋ณด์ ์ธ ๊ถ๊ธ์ฆ์ ๊ฐ์ ธ๋ดค๋ค.
& ๋ ์ฐ์ฐ์๋ก์จ “์ด ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ ธ์จ๋ค” ๋ฅผ ์๋ฏธํ๋ค. ์ฆ ์ด๋ค ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉํ๋ ์ฐ์ฐ์์ด๊ธฐ์ ํ์ ์ ์ ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ์ ํ์ง ์๋ค.
์ ๋ฆฌํ๋ฉด
- *Item ์ “Item ๋ณ์๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ ํ์ ”
- &Item ์ “Item ๋ณ์์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์”
๊ทธ๋ผ Go ๋ ์ ๊ตณ์ด ํฌ์ธํฐ๋ฅผ ๋์ ํ์๊น?
Go ๋ ์์ ์ฑ๊ณผ ๊ฐ๊ฒฐํจ์ด๋ผ๋ ์ธ์ด ์ฒ ํ ์๋ call by value ๋ก ์ค๊ณ๋์ด ๊ฐ๋ฐ์๊ฐ ์ฝ๋์ ๋์์ ๋ช ํํ ์ดํดํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๋ฒ๊ทธ๋ฅผ ์ค์ด๋ฉฐ, ์ง๊ด์ ์ธ ํ๋ก๊ทธ๋๋ฐ ๊ฒฝํ์ ์ ๊ณตํ๋ค. Go ๊ฐ call by reference ๋ก ๋์ํ๋ค๋ฉด, ๋ฐ์ดํฐ๊ฐ ์ด๋์ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋๋์ง ์ถ์ ํ๊ธฐ ์ด๋ ค์ ์ฝ๋์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์ํจ๋ค. Go์ call by value๋ ์ด๋ฐ ๋ณต์ก์ฑ์ ์ค์ด๊ณ ์ฝ๋์ ์์ธก ๊ฐ๋ฅ์ฑ์ ๋์ด๋ ํจ๊ณผ๋ฅผ ๊ฐ์ ธ์๋ค.
์ด๋ฐ ์ธ์ด ์ฒ ํ์ ๊ธฐ์กฐ๋ก Pointer ๋ฅผ ์๊ฐํด๋ณด์.
type HugeStruct struct {
data [1000000]int
// ๋งค์ฐ ํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ๊ตฌ์กฐ์ฒด
}
// ํฌ์ธํฐ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ
func processData(h HugeStruct) {
// 1,000,000๊ฐ์ ์ ์๊ฐ ๋ชจ๋ ๋ณต์ฌ๋จ!
}
// ํฌ์ธํฐ ์ฌ์ฉํ ๊ฒฝ์ฐ
func processDataPtr(h *HugeStruct) {
// ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ง ๋ณต์ฌ (8๋ฐ์ดํธ ์ ๋)
}
ํฌ์ธํฐ๋ ๊ฐ ์์ฒด๋ฅผ ๋ณต์ฌํ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ ๋ฌํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๊ณ , ๋๊ท๋ชจ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ ๋ถํ์ํ ๋ณต์ฌ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค. ์์์ฒ๋ผ HugeStruct ๊ฐ์ ๋๊ท๋ชจ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ผ๋ก ์ ๋ฌํ๋ฉด ํจ์๋ฅผ ํธ์ถํ ๋๋ง๋ค HugeStruct ์ ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋ณต์ฌ๋๋ค. ์ด ๊ณผ์ ์ด ๋ฐ๋ณต๋๋ฉด ์ต์ ์ ๊ฒฝ์ฐ OOM(Out Of Memory)์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ๋ ์๋ค.
๋ฐ๋ฉด ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด?
๋๊ท๋ชจ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ณต์ฌํ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ง ์ ๋ฌํ๋ฏ๋ก ๋ณต์ฌ์ ๋ฐ๋ฅธ ์ค๋ฒํค๋๊ฐ ์ค์ด๋ค๊ณ , ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๋ ํฌ๊ฒ ์ ๊ฐํ ์ ์๋ค. ํจ์ ํธ์ถ ์ ๊ฐ ์์ฒด๊ฐ ์๋ ์ฃผ์๋ฅผ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ๋์ผํ ๋ฐ์ดํฐ์ ์ฌ๋ฌ ๋ณต์ฌ๋ณธ์ ์์ฑํ์ง ์์๋ ๋๋ค. *HugeStruct์ ๊ฐ์ ํฌ์ธํฐ๋ฅผ ํจ์๋ก ์ ๋ฌํ๋ฉด, ํจ์ ๋ด๋ถ์์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ ๋๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ํตํด ์๋ณธ ๋ฐ์ดํฐ์ ์ง์ ์ ๊ทผํ ์ ์๋ค. ํจ์ ๋ด๋ถ์์ ๋ฐ์ดํฐ ์์ ์ด ํ์ํ ๊ฒฝ์ฐ์ ๋ณต์ฌ๋ณธ์ด ์๋ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์์ ํ ์ ์์ด ๋ถํ์ํ ๋ฐ์ดํฐ ๋ณต์ฌ๋ ์ค์ฌ ์ฑ๋ฅ์ ๋์ผ ์ ์๋ค.
์๋ ์ฝ๋๋ pointer ๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์๋๋ฅผ ํ์ ํ ์ ์๋ค๋ ์ ์ ๋ณด์ฌ์ค๋ค.
type User struct {
name string
age int
}
// ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์๊ฐ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๊ฒ์
// ํ์
์๊ทธ๋์ฒ๋ง์ผ๋ก๋ ๋ช
ํํ๊ฒ ์ ์ ์์
func updateAge(u *User) {
u.age += 1
}
// ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์์์ ์์
func displayInfo(u User) {
fmt.Println(u.name, u.age)
}
๋ฉ์๋ ์๊ทธ๋์ฒ์ ํฌ์ธํฐ๋ฅผ ์ ์ํ๋ฉด ํด๋น ํจ์ ๋ด๋ถ์์ ์ธ์๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ ์์ ํ๊ฒ ๋ค๋ ์๋๋ฅผ ๋๋ฌ๋ธ๋ค. ๋ฐ๋ฉด ํฌ์ธํฐ๊ฐ ์๋ ๊ฐ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ์ํ๋ฉด, ํด๋น ํจ์ ๋ด๋ถ์์๋ ๊ฐ์ ์์ ํ์ง ์๊ณ ์ฌ์ฉ(read)๋ง ํ๊ฒ ๋ค๋ ์๋๋ฅผ ๋ํ๋ผ ์ ์๋ค. ํฌ์ธํฐ๊ฐ ๋ค์ ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์์ง๋ง ๋ฐ์ดํฐ ์ํ ๋ณ๊ฒฝ์ ๋ช ํ์ฑ์ ๋๋ฌ๋ด๊ธฐ์ ๊ฐ๋ฐ ์ ์ฝ๋์ ์๋๋ฅผ ๋ช ํํ ํ์ ํ ์ ์๋ค.
๋ฒ์ธ) Java ์ ํฌ์ธํฐ๋?
Java ๋ ํฌ์ธํฐ ๊ฐ๋ ์ด ์๋๋ฐ ์ธ์ด ์์ฒด๊ฐ ์ด๋ฏธ call by reference ๋ก ์ค๊ณ ๋์ด์๊ธฐ ๋๋ฌธ์ด๋ค. ์๋ฐ์ ๊ฒฝ์ฐ ๊ฐ์ฒด๋ฅผ ๋ค๋ฃฐ ๋ ํญ์ ์ฐธ์กฐ(reference)๋ฅผ ํตํด ์ฒ๋ฆฌํ๋๋ฐ, Go์ ํฌ์ธํฐ์ ๋ฌ๋ฆฌ ๋ช ์์ ์ด์ง ์๊ณ ์ธ์ด ์ฐจ์์์ ์๋์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
// Java
class HugeObject {
int[] data = new int[1000000];
void processData() {
// data ์ฒ๋ฆฌ
}
}
void someMethod(HugeObject obj) { // ์ฐธ์กฐ๋ก ์ ๋ฌ๋จ
obj.processData(); // ์๋ณธ ๊ฐ์ฒด์ ๋ฉ์๋ ํธ์ถ
}
// ์ฌ์ฉ
HugeObject huge = new HugeObject();
someMethod(huge); // ์ฐธ์กฐ๋ง ์ ๋ฌ๋จ (์ค์ ๋ฐ์ดํฐ๋ ๋ณต์ฌ๋์ง ์์)
go ์ ๋ฌ๋ฆฌ ํฌ์ธํฐ๋ฅผ ๋ช ์ํ์ง ์๋๋ผ๋ ์ธ์ด ์ฐจ์์์ ์๋์ผ๋ก ์ฐธ์กฐ๋ฅผ ๋๊ธฐ๊ธฐ ๋๋ฌธ์ ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ๊ฐ ๋ฐ์๋์ง ์๋๋ค. ์ฆ ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐ๋ ๊ฒ(์ฒ๋ผ ๋ณด์)์ผ๋ก ๋ฉ์๋ ๋ด๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ฝ๊ณ ์์ ๊น์ง ํ ์ ์๋ค. HugeObject ์ฒ๋ผ ํฐ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ๋๋ ๋น์ฐํ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๋ง๋ฌด๋ฆฌ
Go๊ฐ ํฌ์ธํฐ๋ฅผ ๋์ ํ ์ด์ ๋ ํฌ๊ฒ ์ธ ๊ฐ์ง๋ก ์ ๋ฆฌํ ์ ์๋ค:
- ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ฑ:
- ํฐ ๊ตฌ์กฐ์ฒด๋ ๋ฐ์ดํฐ๋ฅผ ํจ์์ ์ ๋ฌํ ๋ ์ ์ฒด๋ฅผ ๋ณต์ฌํ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ง ์ ๋ฌ
- ๋ถํ์ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ค์ด๊ณ ์ฑ๋ฅ ํฅ์ ๋๋ชจ
- OOM(Out Of Memory) ๊ฐ์ ์ ์ฌ์ ๋ฌธ์ ์๋ฐฉ
- ์ฝ๋ ์๋์ ๋ช
ํ์ฑ:
- ํฌ์ธํฐ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ํตํด ํจ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ๊ฒ์ธ์ง ๋จ์ ์ฐธ์กฐํ ๊ฒ์ธ์ง ๋ช ์ ๊ฐ๋ฅ
- ๋ฉ์๋ ์๊ทธ๋์ฒ๋ง์ผ๋ก๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ ์ฌ๋ถ๋ฅผ ์์ธก ๊ฐ๋ฅ
- ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ํฅ์
- ๊ฐ๋ฐ์์๊ฒ ๋ ๋ง์ ์ ์ด๊ถ ์ ๊ณต:
- Call by value๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ๋, ํ์ํ ๊ฒฝ์ฐ ํฌ์ธํฐ๋ฅผ ํตํ ์ฐธ์กฐ ์ ๋ฌ ๊ฐ๋ฅ
- Java์ ๋ฌ๋ฆฌ ๊ฐ ๋ณต์ฌ์ ์ฐธ์กฐ ์ ๋ฌ์ ๊ฐ๋ฐ์๊ฐ ๋ช ์์ ์ผ๋ก ์ ํ ๊ฐ๋ฅ
- ์ํฉ์ ๋ฐ๋ฅธ ์ต์ ์ ๋ฐฉ๋ฒ ์ ํ ๊ฐ๋ฅ
์ด์ฒ๋ผ Go์ ํฌ์ธํฐ๋ ๋จ์ํ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ค๋ฃจ๋ ๋๊ตฌ๋ฅผ ๋์ด, ์ฑ๋ฅ ์ต์ ํ์ ์ฝ๋ ์๋์ ๋ช ํํ ํํ์ด๋ผ๋ ๋ ๊ฐ์ง ํต์ฌ ๊ฐ์น๋ฅผ ์ ๊ณตํ๋ค. Go๊ฐ ์ถ๊ตฌํ๋ '๋ช ์์ ์ธ ๊ฒ์ด ์์์ ์ธ ๊ฒ๋ณด๋ค ๋ซ๋ค'๋ ์ฒ ํ์ด ํฌ์ธํฐ๋ฅผ ํตํด ์ ๊ตฌํ๋์ด ์์์ ์ ์ ์๋ค.