获取已知结构域的名称
问题描述:
我有代表在数据库对象的结构,像这样:获取已知结构域的名称
type Object struct {
Id string
Field1 string
Field2 int
}
,我想有一个更新数据库中的特定领域的功能每当字段被修改,这些方针的东西:
func (self *Object) SetField1(value string) {
self.Field1 = value
database.Update(self.Id, "Field1", self.Field1) // pseudocode
}
有没有办法来代替"Field1"
硬编码字符串,我的代码是在结构领域的排序和命名的未来变化性?
我对反射包进行了探讨,能够获得表示我正在使用的字段的StructField会很好,但它似乎需要通过硬编码的字段名称字符串或结构中的字段索引(可能会更改)。
答
您可以通过添加一个方法是这样的验证字符串:
func (self *Object) verify(field string) string {
if _, ok := reflect.TypeOf(*self).FieldByName(field); ok {
return field
}
panic("Invalid field name")
}
,然后使字符串到数据库更新时使用它
func (self *Object) SetField1(value string) {
self.Field1 = value
database.Update(self.Id, self.verify("Field1"), self.Field1) // pseudocode
}
但我认为如果你愿意使用反射,那么你最好使用一个通用的setField
方法将字段接受为字符串,并将值作为interface{}
,检查字段和值,设置值并更新数据库。
这样一切都是使用字符串完成的,所以它可能工作或恐慌,并且您不需要记住使用.verify()
方法。
财产以后这样的:
func (self *Object) SetField(field string, value interface{}) {
// verify field and value using reflection
// set the value using reflection
database.Update(self.Id, field, self.Field1)
}
虽然我不认为这会在未导出下地干活。
答
不在您谈论的上下文中。它没有作为参数传递,所以你需要一些其他方式来指定哪个要发送的结构域。这里的心理缺陷是你试图把它设置的功能当它不是它的属性;如其他语言所示,属性之间的主要区别是属性绑定到特定的字段,而您的SetField1
方法绑定到整个结构。该方法不妨设置两个字段。
一般情况下,如果你正在做场反射的东西,并且你想用字段做一些花哨的动态东西,你想使用结构标签。例如,像这样:
type Object struct {
Id string `db:"id"`
Field1 string `db:"field1"`
Field2 int `db:"field2"`
}
您可以访问这些标签,如-A-这样的:
package main
import (
"reflect"
"fmt"
)
func main() {
var x struct {
MyField int `core:"required"`
}
t := reflect.TypeOf(x)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
fmt.Println(field.Name, ":", field.Tag.Get("core"))
}
}
,这不是一个真正的完整的解决方案,但是......在它的问路的问题是不可能的去做。
如果你不知道你的字段的名称,你将如何在数据库中更新它? – Daniel
那么'Object'是'Foo'? –
@系统 - 是的,修正了错字。 – Chris