#go #struct #auto-increment
#Вперед #структура #автоматическое увеличение
Вопрос:
У меня есть набор сотрудников, определенных в JSON-файле:
type PrimitiveEmployee struct {
PrimitiveID string `xml:"ID,attr"`
ContractID []string `xml:"ContractID"`
}
Оба ID
и ContractID
являются буквами, но им не обязательно задается непрерывная последовательность букв. Например, может существовать сотрудник с PrimitiveID=A и другой с PrimitiveID=C, но не сотрудник с PrimitiveID=B.
Я хочу преобразовать эти данные в:
type Employee struct {
ID int
PrimitiveID string
Contracts []Contract
}
Дело в том, что я хочу, чтобы идентификатор сотрудника начинался с 0 и увеличивался на единицу при каждой инициализации структуры. Что-то вроде идентификатора автоинкремента в базе данных или iota в перечислении.
Затем сотрудник с PrimitiveID=A будет автоматически создан с ID = 0, в то время как сотрудник с PrimitiveID = C получит ID = 1.
Я просто не могу понять, как решить это в структуре.
Очень признателен за любую помощь или указания здесь.
Комментарии:
1. Создайте глобальную переменную, содержащую счетчик, и в функции, которая создает экземпляры ваших
Employee
-s, прочитайте эту переменную и увеличьте ее впоследствии. Предположительно, функции будут лучше обслуживать васsync/atomic.AddInt*
(поскольку в противном случае ваш код не может использоваться одновременно запущенными программами). Чтобы ответить, возможно, на незаданный вопрос, нет, у вас не может быть того, что вы хотите, чтобы работать как-то «автоматически», поскольку Go не имеет «конструкторов».2. Если вы строите кучу структур сотрудников в памяти, вы можете поместить их в массив и использовать их смещения для их идентификаторов. Это гарантирует, что они уникальны и концептуально автоматически увеличиваются при добавлении в массив. UUID был бы другим вариантом. Одна из приятных особенностей использования uuid заключается в том, что они не являются последовательными, и поэтому номера сотрудников можно довольно легко угадать.
Ответ №1:
Создайте пользовательский тип для управления уникальным идентификатором приращения:
type autoInc struct {
sync.Mutex // ensures autoInc is goroutine-safe
id int
}
func (a *autoInc) ID() (id int) {
a.Lock()
defer a.Unlock()
id = a.id
a.id
return
}
Таким образом, вы можете использовать его в целевых местах или на уровне пакета:
var ai autoInc // global instance
Затем вы можете создать функции «конструктора», чтобы использовать это:
func NewEmployee() *Employee {
return amp;Employee{
ID: ai.ID(),
}
}
Employee
Затем можно выполнить маршалинг данных JSON, и идентификатор будет сохранен — при условии, что данные JSON не содержат ID
тега.