[Go]

[Go] 슬라이스의 얕은 복사와 깊은 복사 (Shallow Copy and Deep Copy of Slices)

dogfootman 2023. 8. 3. 23:43

개요

슬라이스의 얕은 복사와 깊은 복사에 대해서

 

 

1. 얕은 복사

package main

import (
	"fmt"
	"sort"
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: "A", Age: 1},
		{Name: "B", Age: 2},
		{Name: "C", Age: 3},
	}
	list2 := list1

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age < list2[j].Age
	})

	fmt.Printf("List1 [%p]\n", list1)
	for _, item := range list1 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}

	fmt.Printf("List2 [%p]\n", list2)
	for _, item := range list2 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}
}

결과값:

List1 [0xc0000a8060]
Name: A, Age: 1 [0xc0000a8078]
Name: B, Age: 2 [0xc0000a8090]
Name: C, Age: 3 [0xc0000a80a8]
List2 [0xc0000a8060]
Name: A, Age: 1 [0xc0000a8078]
Name: B, Age: 2 [0xc0000a8090]
Name: C, Age: 3 [0xc0000a80a8]

슬라이스가 같은 주소값(0xc0000a8060)을 가지며 원본도 같이 정렬 된 것을 확인

 

 

2. 깊은 복사 (copy)

package main

import (
	"fmt"
	"sort"
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: "C", Age: 3},
		{Name: "B", Age: 2},
		{Name: "A", Age: 1},
	}

	list2 := make([]*obj, len(list1))

	copy(list2, list1)

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age < list2[j].Age
	})

	fmt.Printf("List1 [%p]\n", list1)
	for _, item := range list1 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}

	fmt.Printf("List2 [%p]\n", list2)
	for _, item := range list2 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}
}

결과값:

List1 [0xc00009c060]
Name: C, Age: 3 [0xc00009c078]
Name: B, Age: 2 [0xc00009c090]
Name: A, Age: 1 [0xc00009c0a8]
List2 [0xc00009c0c0]
Name: A, Age: 1 [0xc00009c0a8]
Name: B, Age: 2 [0xc00009c090]
Name: C, Age: 3 [0xc00009c078]

원본 슬라이스(0xc00009c060)와 다른 주소값(0xc00009c0c0)을 가진 것을 확인

 

https://pkg.go.dev/builtin#copy

 

builtin package - builtin - Go Packages

Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons

pkg.go.dev

 

 

3. 깊은 복사 (append)

package main

import (
	"fmt"
	"sort"
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: "C", Age: 3},
		{Name: "B", Age: 2},
		{Name: "A", Age: 1},
	}

	var list2 []*obj
	list2 = append(list2, list1...)

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age < list2[j].Age
	})

	fmt.Printf("List1 [%p]\n", list1)
	for _, item := range list1 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}

	fmt.Printf("List2 [%p]\n", list2)
	for _, item := range list2 {
		fmt.Printf("Name: %s, Age: %d [%p]\n", item.Name, item.Age, item)
	}
}

결과값:

List1 [0xc000116060]
Name: C, Age: 3 [0xc000116078]
Name: B, Age: 2 [0xc000116090]
Name: A, Age: 1 [0xc0001160a8]
List2 [0xc0001160c0]
Name: A, Age: 1 [0xc0001160a8]
Name: B, Age: 2 [0xc000116090]
Name: C, Age: 3 [0xc000116078]

원본 슬라이스(0xc000116060)와 다른 주소값(0xc0001160c0)을 가진 것을 확인

 

 

https://pkg.go.dev/builtin#append

 

builtin package - builtin - Go Packages

Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons

pkg.go.dev