개요
슬라이스의 얕은 복사와 깊은 복사에 대해서
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
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