개요
- golang에서 얕은 복사, 깊은 복사 구현
- 깊은 복사의 경우 직렬화 방식을 사용
- 실제 메모리 주소를 출력하여 차이 확인
코드
study/copy.go
package study
import (
"bytes"
"encoding/gob"
"fmt"
)
type sampleStruct struct {
SampleNum int
SampleStr string
SamplePos *pos
SampleSlice []int
}
type pos struct {
X int
Y int
}
func ShallowCopy() {
sample := sampleStruct{
SampleNum: 10,
SampleStr: "abc",
SamplePos: &pos{X: 1, Y: 2},
SampleSlice: []int{1, 2, 3},
}
newSample := sample
newSample.SampleNum = 11
newSample.SampleStr = "cde"
newSample.SamplePos.X = 3
newSample.SamplePos.Y = 4
newSample.SampleSlice[1] = 99
fmt.Printf("%v\n", sample)
fmt.Printf("%v\n\n", newSample)
fmt.Printf("samplePos:\t %p, %p\n", &sample.SamplePos, sample.SamplePos)
fmt.Printf("newSamplePos:\t %p, %p\n", &newSample.SamplePos, newSample.SamplePos)
fmt.Printf("sampleSlice:\t %p, %p\n", &sample.SampleSlice, sample.SampleSlice)
fmt.Printf("newSampleSlice:\t %p, %p\n", &newSample.SampleSlice, newSample.SampleSlice)
}
func DeepCopy() {
sample := sampleStruct{
SampleNum: 10,
SampleStr: "abc",
SamplePos: &pos{X: 1, Y: 2},
SampleSlice: []int{1, 2, 3},
}
var newSample sampleStruct
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
decoder := gob.NewDecoder(&buffer)
err1 := encoder.Encode(sample)
if err1 != nil {
fmt.Println(err1)
}
err2 := decoder.Decode(&newSample)
if err2 != nil {
fmt.Println(err2)
}
newSample.SampleNum = 11
newSample.SampleStr = "cde"
newSample.SamplePos.X = 3
newSample.SamplePos.Y = 4
newSample.SampleSlice[1] = 99
fmt.Printf("%v\n", sample)
fmt.Printf("%v\n\n", newSample)
fmt.Printf("samplePos:\t %p, %p\n", &sample.SamplePos, sample.SamplePos)
fmt.Printf("newSamplePos:\t %p, %p\n", &newSample.SamplePos, newSample.SamplePos)
fmt.Printf("sampleSlice:\t %p, %p\n", &sample.SampleSlice, sample.SampleSlice)
fmt.Printf("newSampleSlice:\t %p, %p\n", &newSample.SampleSlice, newSample.SampleSlice)
}
main.go
package main
import (
"codeTest/study"
)
func main() {
study.ShallowCopy()
fmt.Println("----------------------------------------------")
study.DeepCopy()
}
출력
{10 abc 0x140001341c0 [1 99 3]}
{11 cde 0x140001341c0 [1 99 3]}
samplePos: 0x14000133518, 0x140001341c0
newSamplePos: 0x14000133558, 0x140001341c0
sampleSlice: 0x14000133520, 0x14000144018
newSampleSlice: 0x14000133560, 0x14000144018
----------------------------------------------
{10 abc 0x14000134210 [1 2 3]}
{11 cde 0x140001344f0 [1 99 3]}
samplePos: 0x14000133618, 0x14000134210
newSamplePos: 0x14000133658, 0x140001344f0
sampleSlice: 0x14000133620, 0x14000144048
newSampleSlice: 0x14000133660, 0x14000144060
결론
- int, string 등은 얕은 or 깊은 복사에 상관없이 값이 복사됨
- slice, map, chan 등은 레퍼런스 변수
- 레퍼런스 변수의 얕은 복사의 경우 변수 주소는 다르지만, 가리키는 주소는 동일
- 레퍼런스 변수의 깊은 복사의 경우 변수 주소 및 가리키는 주소까지 다름