Как создать поле идентификатора автоинкремента

#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 тега.

https://play.golang.org/p/0iTaQSzTPZ_j