Search code examples
gostructauto-increment

How to create an autoincrement ID field


I have a set of employees defined in a JSON-file:

type PrimitiveEmployee struct {
    PrimitiveID     string   `xml:"ID,attr"`
    ContractID      []string `xml:"ContractID"`
}

Both ID and ContractID is letters, but they are not necessarily given continuous sequence of letters. For instance, there might exist an employee with PrimitiveID=A and another with PrimitiveID=C, but not an employee with PrimitiveID=B.

I want to convert this data into:

type Employee struct {
    ID              int
    PrimitiveID     string
    Contracts       []Contract
}

The thing is, I want the the employee-ID to start at 0 and increment with one for each time the struct is initialized. Sort of like a an autoincrement ID in a database or iota in a enum.

The employee with PrimitiveID=A will then automatically be created with ID=0, while the employee with PrimitiveID=C will get ID=1.

I just cant figure out how to solve this in a struct.

Greatly appreciate any help or pointers here.


Solution

  • Create a custom type to manage the unique incrementing ID:

    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
    }
    

    So you can use it in targeted places or at the package level:

    var ai autoInc // global instance
    

    You can then create "constructor" functions to leverage this:

    func NewEmployee() *Employee {
        return &Employee{
            ID: ai.ID(),
        }
    }
    

    Marshaling JSON data to Employee can then be performed and the ID will be preserved - provided the JSON data does not container an ID tag.

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