Как клонировать структуру с неэкспортированным полем?

Если у меня есть тип, определенный как:

type T struct {
    S  string
    is []int
}

тогда как я могу пойти клонировать объект этого типа? Если я делаю простое задание:

p := T{"some string", []int{10, 20}}
q := p

Затем любые изменения, внесенные в[]int влияет на оба объекта. посколькуT.is не экспортируется, его нельзя скопировать явно, даже если он извлечен с использованием отражения.

В настоящее время я поставляюClone Метод в пакете самого типа. Но это не помогает с подобными типами в других пакетах. Есть ли другой способ сделать это?

Ответы на вопрос(1)

Решение Вопроса

только декларирующий пакет может изменить их.

Обратите внимание, что еслиT тип объявлен в другом пакете, вы даже не можете написать:

p := somepackage.T{"some string", []int{10, 20}}

потому что это будет неявно пытаться установить необъявленноеT.is поле и, следовательно, приводит к ошибке времени компиляции:

implicit assignment of unexported field 'is' in somepackage.T literal

Если вы являетесь владельцем (или можете изменить) пакета, лучше всего предоставитьClone() метод или функцию, или предоставитьSetIs() метод для типаT, Если сторонний пакет не предоставляет такую ​​функциональность, вы ничего не можете с этим поделать.

Обратите внимание, что с помощью пакетаunsafe можно делать такие вещи, но как следует из названия: этонебезопасный и ты должен держаться подальше от этого.

Также обратите внимание, что вы можете создавать новые значенияT гдеis не копируется, но будетнулевое значение своего типа (который в случае[]int будетnil):

var r somepackage.T
s := somepackage.T{S: p.S}

fmt.Printf("%q\n", r)
fmt.Printf("%q\n", s)

Который будет выводить:

{"" []}
{"some string" []}

Но вы не можете установить ненулевое значение для неэкспортированного поляT.is.

Ваш ответ на вопрос