Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

All entries in slice end up identical after copying from another slice

I have a slice of uuid.UUID elements. From the source, a uuid.UUID is just a type alias for a byte array: type UUID [16]byte.

I’m trying to convert this slice of uuid.Uuids to a slice of []byte using the following code:

package main

import (
    "fmt"
    "github.com/google/uuid"
)

func main() {
    ids := []uuid.UUID {
        uuid.New(),
        uuid.New(),
        uuid.New(),
    }
    fmt.Printf("ids: %v\n", ids)
    idBytes := make([][]byte, len(ids))
    for i, id := range ids {
        idBytes[i] = id[:]
    }
    fmt.Printf("idBytes: %x\n", idBytes)
}

playgroud link

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

For some reason, this produces the following output:

ids: [66b4bb26-3c1f-4dd7-a608-aa8f799e4bfe 014e0537-c326-4021-be38-165f49595eed 5c71efff-ddb5-4f6e-8f85-c1dab013b5d1]
idBytes: [5c71efffddb54f6e8f85c1dab013b5d1 5c71efffddb54f6e8f85c1dab013b5d1 5c71efffddb54f6e8f85c1dab013b5d1]

There are clearly 3 distinct UUIDs, but the output slice contains only the last one, repeated 3 times. What’s going on here?

Things I’ve tried:

  1. Use a non-slice type instead of a slice type (that is, use []uint64 as input and output instead of []uuid.UUID and [][]byte). This shows the expected behavior (I see 3 distinct values instead of the last value repeated 3 times), but it doesn’t actually solve my problem.
  2. Set only the last element (put the idBytes[i] = id[:] inside an if i == len(ids) - 1 block). This sets only the last element (the first two elements remain nil).

>Solution :

Two facts to consider:

  • id is of type UUID, which is [16]byte.
  • Loop variables a overwritten at each iteration

Thus, there is only one instance of id is allocated and shared between all iterations of the for loop. Since id is an array (not a slice), contents of each UUID are copied to id. All the slices id[:], thus, point to the same shared underlying byte array, which, when the loop ends, contains the latest contents of id.

To fix:

idBytes[i] = ids[i][:]

which will create separate slices for each UUID.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading