如果需要,我的程序包需要能够让我的用户显式定义字段后端数据库列名称。
默认情况下,我将使用字段名称-但有时它们将需要手动指定列名称,就像JSON包一样-如果需要,unmarshal使用显式名称。
如何在代码中使用此显式值?我什至不知道这叫什么,所以Google目前真的让我失望。
例如,这是JSON的解组功能所需要的:
type User struct { Name string LastName string `json:"last_name"` CategoryId int `json:"category_id"` }
我需要使用这样的东西吗?
// Paprika is my package name. type User struct { Name string LastName string `paprika:"last_name"` CategoryId int `paprika:"category_id"` }
我的程序包将用于构造SQL查询,而我不能仅仅依靠字段的名称-我需要能够让他们手动设置列名称。因此,此刻仅处理定义的列。
// Extracts resource information using reflection and // saves field names and types. func loadTypeToSchema(resource interface{}) { resourceType := reflect.TypeOf(resource) // Grab the resource struct Name. fullName := resourceType.String() name := fullName[strings.Index(fullName, ".")+1:] // Grabs the resource struct fields and types. fieldCount := resourceType.NumField() fields := make(map[string]string) for i := 0; i <= fieldCount-1; i++ { field := resourceType.Field(i) fields[field.Name] = field.Type.Name() } // Add resource information to schema map. schema[name] = fields }
首先,您所谓的装饰器实际上称为标记。您可以使用反射读取这些标签。该reflect软件包甚至有自己的示例。
reflect
不过,这是另一个示例,该示例打印结构成员的所有标签(单击播放):
type Foo struct { A int `tag for A` B int `tag for B` C int } func main() { f := Foo{} t := reflect.TypeOf(f) for i := 0; i < t.NumField(); i++ { fmt.Println(t.Field(i).Tag) } }
请注意,如果f是一个指针,例如a *Foo,则必须首先间接(取消引用)该值,否则返回的类型TypeOf不是结构而是指针,NumField并且Field()也不起作用。
f
*Foo
TypeOf
NumField
Field()