我想要迭代结构体的字符串字段,以便进行一些清理/验证(使用 strings.TrimSpace
,strings.Trim
等)。
现在我的代码有一个混乱的 switch-case,不太可扩展,而且这不是我的应用程序的热点(一个 web 表单),因此在这里利用 reflect
似乎是一个不错的选择。
然而,我对如何实现这个目标有些困惑,反射文档对我来说有点难以理解(我已经查看了一些其他的验证包,但它们太重量级了,而且我已经在使用 gorilla/schema 进行非编组部分):
- 迭代结构体
- 对于每个字符串类型的字段,使用
strings
包中所需的任何操作(例如:field = strings.TrimSpace(field)
) - 如果存在 field.Tag.Get("max"),我们将使用该值(strconv.Atoi,然后 unicode.RuneCountInString)
提供一个与错误接口类型兼容的错误切片
type FormError []string
type Listing struct {
Title string `max:"50"`
Location string `max:"100"`
Description string `max:"10000"`
ExpiryDate time.Time
RenderedDesc template.HTML
Contact string `max:"255"`
}
// Iterate over our struct, fix whitespace/formatting where possible
// and return errors encountered
func (l *Listing) Validate() error {
typ := l.Elem().Type()
var invalid FormError
for i = 0; i < typ.NumField(); i++ {
// Iterate over fields
// For StructFields of type string, field = strings.TrimSpace(field)
// if field.Tag.Get("max") != "" {
// check max length/convert to int/utf8.RuneCountInString
if max length exceeded, invalid = append(invalid, "errormsg")
}
if len(invalid) > 0 {
return invalid
}
return nil
}
func (f FormError) Error() string {
var fullError string
for _, v := range f {
fullError =+ v + "\n"
}
return "Errors were encountered during form processing: " + fullError
}
提前致谢。
field.Tag.Get("max")
- 如果不是字段,我应该在哪个方法上调用Tag
?http://play.golang.org/p/yMRLFCW4vt - elithrarmsValue.Type()
重新获取字段,然后从相应的字段获取标签。 - Linear,以提供访问字段
Tag`的快捷方式。再次感谢您的帮助! - elithrar