我试图编写一个可以在Golang中使用不同自定义类型的辅助函数,但我无法弄清楚如何按照我想要的方式完成它。在这种情况下(顺便说一下,我正在构建一个返回实现HAL协议的JSON对象的API。这只是意味着资源和关系作为链接返回而不仅仅是ID')。
我的应用程序中有许多模型,例如学生,校长,学校等... 这些模型中的每一个都有许多字段,一些相同,一些不同。理想情况下,我喜欢可以迭代结构字段的函数,并更改结构中的另一个字段。最大的挑战是这些结构可以是学生,校长,学校等类型......
型号:
type Person struct {
halgo.Links
Id bson.ObjectId
Firstname string
Lastname string
Email string
}
type Student struct {
Person `bson:",inline"`
School mgo.DBRef
}
type School struct {
Id bson.ObjectId
Address []string
Name string
Description string
}
然后,我想要一个基本上可以接受任何这些结构的函数,遍历字段(使用reflect
),并对每个字段执行某些操作。
我尝试了一个带interface{}
的函数,但问题是你必须键入断言参数才能访问任何字段。即使你有了这个,你仍然需要为每种类型/模型编写单独的函数。
func GenerateLinksHelper(m interface{}) {
...
}
最终,我试图找到一种方法来编写一个函数,该函数接受一个有点任意的结构并对可能存在或不存在的字段执行操作。
答案 0 :(得分:4)
我不确定你想要做什么,但通过反思,你可以看到一个字段是否存在,然后用它做一些事情。
来自“反思法则”文章(http://blog.golang.org/laws-of-reflection)的例子。玩:http://play.golang.org/p/neU3j2MYvz
package main
import (
"fmt"
"reflect"
)
type T1 struct {
A int
B string
}
type T2 struct {
A int
}
func fct(i interface{}) {
s := reflect.ValueOf(i).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
if typeOfT.Field(i).Name == "B" {
fmt.Printf("I am %s and I have a field B: %s\n", typeOfT.Name(), f.Interface())
}
}
}
func main() {
t1 := T1{23, "skidoo"}
t2 := T2{23}
fct(&t1)
fct(&t2)
}