Важность приемников указателей при копировании экземпляров
При манипулировании данными крайне важно понимать нюансы передачи значений по ссылке или по значению. В Go методы могут быть определены с помощью приемников значений или указателей, и важно понимать последствия этого выбора, особенно при копировании экземпляров.
Приемники значений
Методы с получателями значений работают с копией полученного значения. Любые изменения, внесенные в метод, не повлияют на исходное значение. Это гарантирует, что вызов методов в скопированных экземплярах не поставит под угрозу исходные данные.
Приемники указателей
И наоборот, методы с приемниками указателей обеспечивают прямой доступ и изменение исходного значения. . Такие методы могут привести к мутации данных, что может привести к незаметным и непредвиденным побочным эффектам. Копирование экземпляров с помощью приемников указателей сопряжено с риском возникновения несоответствий между исходными и скопированными данными.
Пример: Wrapper Struct
Чтобы проиллюстрировать проблему, рассмотрим тип под названием Wrapper с полями v (значение) и p (указатель на значение):
type Wrapper struct {
v int
p *int
}
Метод Set() с приемником указателя изменяет как v, так и указанное значение:
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
Предположим, у нас есть экземпляр Wrapper a:
a := Wrapper{v: 0, p: new(int)}
Calling Set() on a изменит и v, и *p:
a.Set(1)
Теперь, если мы скопируем a, чтобы создать b, мы ожидаем, что оба экземпляра будут иметь согласованные значения :
b := a
Однако последующие модификации a с использованием Set() не будут распространяться на b из-за копирования указателя p, что приводит к противоречивым данным:
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
a.Set(1)
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
Вывод:
a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1
Заключение
При работе с типами, имеющими методы с приемниками указателей, крайне важно избегать копирования экземпляров, чтобы предотвратить несогласованность данных. Вместо этого оперируйте значениями указателей, чтобы гарантировать, что изменения отражаются во всех экземплярах, которые ссылаются на одни и те же базовые данные.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3