go - 如何填充作为函数引用传递的接口切片
问题描述
我有一个小例子,我尝试在函数中填充 []Entry (其中 Entry 是一个接口)切片,当参数是单个条目时,这可以正常工作,但是当尝试传递一个条目切片时,我无法弄清楚我的通过指针的方式。
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)
}
}
}
以及我尝试使用它的测试:
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())
}
取决于我是声明GetByCollection(collectionName string, entries []Entry)
还是GetByCollection(collectionName string, entries *[]Entry)
得到:
# github.com/mojlighetsministeriet/next/temp
./main.go:39:4: invalid indirect of entries (type []Entry)
或者
# 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
我应该如何编写以便我可以通过调用 GetByCollection 来选择条目类型,比如填充的 []Book 或 []Author 切片?
我可能需要以某种方式重构,最后我喜欢类似于 GORM 的查询方法(http://gorm.io/docs/query.html#Query)的东西,db.Find(&users)
但喜欢GetByCollection("books", &books)
解决方案
反射需要使用不同的切片类型。这是如何做到的:
func GetByCollection(collectionName string, result interface{}) {
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"}`,
},
}
slice := reflect.ValueOf(result).Elem()
elementType := slice.Type().Elem()
for _, entryData := range collections[collectionName] {
v := reflect.New(elementType)
json.Unmarshal([]byte(entryData), v.Interface())
slice.Set(reflect.Append(slice, v.Elem()))
}
}
像这样称呼它:
var books []Book
GetByCollection("books", &books)
推荐阅读
- visual-studio-code - 在不更改 .vscode 文件夹的情况下更改 vscode 配置
- linux - 上传到 Hbase 时数据大小减小
- image - 如何填充图像中的像素间隙
- angular - 如何以角度减少图像的模糊或增加亮度
- r - 如何在 R 中重新组合列
- reactjs - reactjs中的词法范围是什么
- angular - 使用 Angular 11 将我的 REST API(Spring boot)中的事件读入我的完整日历
- json - 角材料未对表中的数字进行排序
- c# - 通过 Windows 服务 C# .net 中的 zkemkeeper.dll 连接到设备
- javascript - 突出显示焦点上的文本 - 剑道组合框