[Go] 얕은 복사, 깊은 복사

natae·2022년 8월 19일
0

Golang

목록 보기
6/11

개요

  • 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 등은 레퍼런스 변수
  • 레퍼런스 변수의 얕은 복사의 경우 변수 주소는 다르지만, 가리키는 주소는 동일
  • 레퍼런스 변수의 깊은 복사의 경우 변수 주소 및 가리키는 주소까지 다름
profile
서버 프로그래머

0개의 댓글