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が完全に独立していることを保証する深いコピーが実現されました。

bannerAds