DevGang
Авторизоваться

Создание копии структур в 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 - две отдельные переменные, но при сравнении их свойств по свойствам они одинаковы.

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

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

Например

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

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

Нужна глубокая копия.

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

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

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

	nikita.friends = make([]string, len(wilson.friends))
	copy(nikita.friends, wilson.friends)

	nikita.friends = append(nikita.friends, "Syd")

	fmt.Println(wilson)
	fmt.Println(nikita)
}

Пример

Вышеприведенный код приведет к тому, что wilson будет {7 Wilson [Tom Tabata Willie]} и nikita {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)

	nikita.friends = append(nikita.friends, "Syd")

	fmt.Println(wilson)
	fmt.Println(nikita)
}
#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

Поделитесь своим опытом, расскажите о новом инструменте, библиотеке или фреймворке. Для этого не обязательно становится постоянным автором.

Попробовать

В этом месте могла бы быть ваша реклама

Разместить рекламу