Создание копии структуры в Go

Структурную переменную в Go можно очень легко скопировать в другую переменную с помощью оператора присваивания:

package main

import ( “fmt” )

type Dog struct { age int name string }

func main() { roger := Dog{5, “Roger”} mydog := roger if roger == mydog { fmt.Println(“Roger and mydog are equal structs”) } }

играть в

mydogиroger- это две отдельные переменные, но при сравнении их по свойствам они абсолютно идентичны.

Теперь мы можем изменить каждое свойство этих переменных, не затрагивая другой объект, потому чтоDogstruct содержит базовые типы, которые копируются по значению.

Если бы у нас был ссылочный тип в нашей структуре, это было бы не так просто, потому чтоpointerбудет скопировано, а не значение, поэтому это было бымелкая копия.

Например

type Cat struct {
    age int
    name string
    friends []string
}

Список друзей нашей кошки - это фрагмент, ссылочный тип (вместе с указателями, картами, функциями и каналами), поэтому, если у вас есть объект cat, и вы скопируете его, как мы сделали для примера с собакой выше, вы не смогли бы измените свойство friends, не затрагивая и другой объект.

Аглубокая копиянеобходим.

Глубокая копия структуры

Вы можете выполнить такое глубокое копирование вручную. В случае среза вы можете выполнить копирование следующим образом:

package main

import ( “fmt” )

type Cat struct { age int name string friends []string }

func main() { wilson := Cat{7, “Wilson”, []string{“Tom”, “Tabata”, “Willie”}} nikita := wilson

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = make([]<span style="color:#66d9ef">string</span>, len(<span style="color:#a6e22e">wilson</span>.<span style="color:#a6e22e">friends</span>))
copy(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#a6e22e">wilson</span>.<span style="color:#a6e22e">friends</span>)

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = append(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#e6db74">"Syd"</span>)

<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">wilson</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">nikita</span>)

}

играть в

Приведенный выше код приведет кУилсонсуществование{7 Wilson [Tom Tabata Willie]}иНикитасуществование{7 Wilson [Tom Tabata Willie Syd]}

Таким образом, вы можете видеть, что срез - это совершенно другой объект, а не просто ссылка на тот же самый срез.

Использование библиотеки глубокого копирования

https://github.com/jinzhu/copierявляется (одной из многих) библиотек / помощников глубокого копирования. Это упрощает глубокое копирование структуры без явного управления каждым полем. Вот пример, все, что нам нужно, этоcopier.Copy(&nikita, &wilson)и мы настроены:

package main

import ( “fmt” github.com/jinzhu/copier )

type Cat struct { age int name string friends []string }

func main() { wilson := Cat{7, “Wilson”, []string{“Tom”, “Tabata”, “Willie”}} nikita := Cat{} copier.Copy(&nikita, &wilson)

<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span> = append(<span style="color:#a6e22e">nikita</span>.<span style="color:#a6e22e">friends</span>, <span style="color:#e6db74">"Syd"</span>)

<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">wilson</span>)
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">nikita</span>)

}


Больше руководств по go: