I have a small example where I try to populate a []Entry (where Entry is an interface) slice inside a function, this works fine when the argument is a single Entry, but when trying to pass a slice of entries I cannot figure my way through the pointers.
package temp
import (
"encoding/json"
uuid "github.com/satori/go.uuid"
)
type BaseEntry struct {
ID uuid.UUID
}
func (entry *BaseEntry) GetID() uuid.UUID {
return entry.ID
}
type Entry interface {
GetID() uuid.UUID
}
func GetByCollection(collectionName string, entries []Entry) {
// This could be a lookup in a database or filesystem
collections := map[string][]string{
"books": []string{
`{"ID": "c8cc718d-94a9-4605-a4bb-05d5aa067fd6", "Title": "Nils Holgersson", "Author": "d89e4a0a-6a65-4754-9090-f8b6c7d6eeec"}`,
`{"ID": "46ad379e-17f2-4961-b615-d4301160f892", "Title": "Ronja rövardotter", "Author": "a1bba636-0700-474f-8fe8-2ad3ec9d061c"}`,
},
"authors": []string{
`{"ID": "d89e4a0a-6a65-4754-9090-f8b6c7d6eeec", "Name": "Selma Lagerlöf"}`,
`{"ID": "a1bba636-0700-474f-8fe8-2ad3ec9d061c", "Name": "Astrid Lindgren"}`,
},
}
if collections[collectionName] != nil {
for _, entryData := range collections[collectionName] {
entry := BaseEntry{}
json.Unmarshal([]byte(entryData), &entry)
*entries = append(*entries, &entry)
}
}
}
And the tests where I try to use this:
package temp_test
import (
"testing"
"github.com/mojlighetsministeriet/next/temp"
uuid "github.com/satori/go.uuid"
"github.com/stretchr/testify/assert"
)
type Book struct {
temp.BaseEntry
}
func TestPopulate(test *testing.T) {
books := []Book{}
temp.GetByCollection("books", &books)
assert.NotEqual(test, uuid.Nil, books[0].GetID())
}
Depending if I declare GetByCollection(collectionName string, entries []Entry)
or GetByCollection(collectionName string, entries *[]Entry)
I get either:
# github.com/mojlighetsministeriet/next/temp
./main.go:39:4: invalid indirect of entries (type []Entry)
or
# github.com/mojlighetsministeriet/next/temp_test
./main_test.go:17:32: cannot use &books (type *[]Book) as type *
[]temp.Entry in argument to temp.GetByCollection
How should I write so that I can choose the entry type by calling GetByCollection with say either a []Book or []Author slice that get populated?
I probably need to refactor somehow, in the end I like something similar to GORM's Query method (http://gorm.io/docs/query.html#Query) db.Find(&users)
but like GetByCollection("books", &books)