我正在尝试编写一个可以在Golang中接受不同自定义类型的辅助函数,但我无法弄清楚如何以我想要的方式做到这一点。情况是这样的(顺便说一下,我正在构建一个返回实现HAL协议的JSON对象的API)。这意味着资源和关系将作为链接而不是简单的ID返回。
我有许多模型在我的应用程序,如学生,校长,学校等…每一个模型都有很多领域,有些相同,有些不同。理想情况下,我想要一个可以遍历结构体的字段并更改结构体中的另一个字段的函数。最大的挑战是这些结构可以是Student、Principal、School等类型。
模型:
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{}) {
...
}
最终,我试图找到一种方法来编写一个函数,它接受一个有点任意的结构,并对可能存在或不存在的字段执行操作。
我不确定理解你想做什么,但是通过反射,你可以看到一个字段是否存在,然后用它做一些事情。
来自"反射定律"文章的例子(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: %sn", typeOfT.Name(), f.Interface())
}
}
}
func main() {
t1 := T1{23, "skidoo"}
t2 := T2{23}
fct(&t1)
fct(&t2)
}