Golangにおける、深いコピーと浅いコピーの違いは何ですか?
Go言語では、ディープコピー(deep copy)とシャローコピー(shallow copy)はデータの複製に関する2つの概念です。
浅いコピーとは、データ構造に対して参照(アドレス)のみをコピーし、実際の内容はコピーしないことを指します。これは、新しいデータ構造と古いデータ構造が同じ基礎データを共有しており、一方を変更すると他方に影響を与えることを意味します。Go言語では、ほとんどの組み込み型(int、string、slice、map、channelなど)の代入操作は浅いコピーです。
サンプルコード:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
p1 := Person{Name: "Alice", Age: 30}
p2 := p1 // 浅拷贝
p1.Name = "Bob"
p1.Age = 40
fmt.Println(p1) // 输出: {Bob 40}
fmt.Println(p2) // 输出: {Bob 40}
}
上記の例では、p1とp2が同じPersonオブジェクトを共有しているため、p1の変更はp2にも影響します。
深いコピーとは、データ構造を階層ごとに複製し、すべての内容を複製することを指します。これには、基本データと参照データが含まれます。つまり、新しいデータ構造と古いデータ構造は完全に独立しており、1つを変更してももう1つに影響を与えません。Go言語では、カスタム構造体タイプに対して、深いコピーを実現するために、json.Marshalやjson.Unmarshal関数を使用してシリアライズおよびデシリアライズを行うか、または各フィールドを手動で階層ごとにコピーする必要があります。
サンプルコード:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
p1 := Person{Name: "Alice", Age: 30}
p2 := deepCopy(p1) // 深拷贝
p1.Name = "Bob"
p1.Age = 40
fmt.Println(p1) // 输出: {Bob 40}
fmt.Println(p2) // 输出: {Alice 30}
}
func deepCopy(src Person) Person {
var dst Person
data, _ := json.Marshal(src)
json.Unmarshal(data, &dst)
return dst
}
上記の例では、json.Marshalとjson.Unmarshal関数を使用して、Personオブジェクトをシリアライズおよびデシリアライズし、p1とp2が完全に独立していることを保証する深いコピーが実現されました。