我有一个表示数据库中对象的结构,如:
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会很好,但它似乎需要通过硬编码字符串的字段名称,或结构中的字段索引(可能会发生变化)。
答案 0 :(得分:6)
不在你所谈论的背景下。它不作为参数传入,因此您需要一些其他方法来指定要发送的结构字段的。这里的心理差距是你试图将那个集合函数视为一个属性,而不是它;如其他语言所示,属性之间的关键区别在于属性绑定到特定的字段,而您的SetField1
方法绑定到整个结构。该方法也可以设置两个字段。
一般来说,如果你正在做一些场上反射的东西,并且你想用字段做一些花哨的动态东西,你想要使用struct标签。例如,像这样:
type Object struct {
Id string `db:"id"`
Field1 string `db:"field1"`
Field2 int `db:"field2"`
}
您可以访问这些标签,例如-a-this:
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"))
}
}
这不是一个完整的解决方案,但是......问题的方式是不可能的。
答案 1 :(得分:3)
您可以通过添加如下方法来验证字符串:
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
方法,并将值作为{{1检查字段和值,设置值并更新数据库。
这样一切都是使用字符串完成的,所以它会工作或恐慌,你不需要记住使用interface{}
方法。
像:
.verify()
虽然我认为这不适用于未出口的字段。