Go 如何填充作为函数引用传递的接口片段
我有一个小例子,我尝试在函数中填充[]条目的(其中条目的是接口)片段,当参数是单个条目时,这很好,但是当尝试传递条目的片段时,我无法找到通过指针的方法Go 如何填充作为函数引用传递的接口片段,go,struct,types,slice,Go,Struct,Types,Slice,我有一个小例子,我尝试在函数中填充[]条目的(其中条目的是接口)片段,当参数是单个条目时,这很好,但是当尝试传递条目的片段时,我无法找到通过指针的方法 package temp import ( "encoding/json" uuid "github.com/satori/go.uuid" ) type BaseEntry struct { ID uuid.UUID } func (entry *BaseEntry) GetID() uuid.UUID {
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字符串,entries[]Entry)
还是GetByCollection(collectionName字符串,entries*[]Entry)
# github.com/mojlighetsministeriet/next/temp
./main.go:39:4: invalid indirect of entries (type []Entry)
或
我应该如何编写,以便可以通过调用GetByCollection来选择条目类型,比如说使用[]Book或[]Author片段填充
我可能需要以某种方式进行重构,最终我喜欢类似于GORM的查询方法()
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)
使用不同的切片类型需要反射。以下是如何做到这一点:
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)
您应该使用
entries*[]Entry
作为函数的参数。但请注意,在Go中,[]Book
不可分配/转换到[]Entry
,即使Book
实现了Entry
,您也必须循环[]Book
来创建[]Entry
切片。。。。看这里,我不认为这是测试你的功能的好方法,为什么你不实现你的接口并把它传递给你的测试呢?!感谢@mkopriva提供的链接,似乎我可以从中得到一些东西,感谢您对输入界面->书籍转换解释的澄清。不知何故,当我发送一本&Book并将其作为一个条目并执行json.Unmarshal(dataString,Book)时,这就起到了作用。但是当我发送*[]条目或[]条目时,我无法附加到切片。我可以看看它是否可以返回一个新的片段。谢谢@Danichetta,我试图实现的是有一种方法,可以让您读取/查询/删除JSON文件(在示例中,我将代码简化为一些字符串),作为一个小型数据库实验,因此,除了需要实现Entry之外,我无法预先知道需要支持哪些结构。关于如何测试函数,您还有其他建议吗?您应该使用entries*[]Entry
作为函数的参数。但请注意,在Go中,[]Book
不可分配/转换到[]Entry
,即使Book
实现了Entry
,您也必须循环[]Book
来创建[]Entry
切片。。。。看这里,我不认为这是测试你的功能的好方法,为什么你不实现你的接口并把它传递给你的测试呢?!感谢@mkopriva提供的链接,似乎我可以从中得到一些东西,感谢您对输入界面->书籍转换解释的澄清。不知何故,当我发送一本&Book并将其作为一个条目并执行json.Unmarshal(dataString,Book)时,这就起到了作用。但是当我发送*[]条目或[]条目时,我无法附加到切片。我可以看看它是否可以返回一个新的片段。谢谢@Danichetta,我试图实现的是有一种方法,可以让您读取/查询/删除JSON文件(在示例中,我将代码简化为一些字符串),作为一个小型数据库实验,因此,除了需要实现Entry之外,我无法预先知道需要支持哪些结构。关于如何测试我的功能,你还有其他建议吗?这看起来很不错,我现在正在尝试。谢谢你,这正是我想要的!很好用!:这看起来真的很好,我现在正在尝试谢谢你这正是我想要的!很好用!:D