郎朗坤
该程序读取自身,将标签添加valid:MaxSize(2)到属性structone.fieldone,然后将更新的程序打印到os.Stdout。package mainimport ( "go/ast" "go/printer" "go/token" "log" "os" "strings" "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/loader")type structone struct { fieldone string fieldtwo string}func main() { var conf loader.Config _, err := conf.FromArgs([]string{"."}, false) if err != nil { log.Fatal(err) } prog, err := conf.Load() if err != nil { log.Fatal(err) } astutil.Apply(prog.InitialPackages()[0].Files[0], addTag("structone.fieldone", "`valid:MaxSize(2)`"), nil) printer.Fprint(os.Stdout, prog.Fset, prog.InitialPackages()[0].Files[0])}func addTag(p string, tag string) func(*astutil.Cursor) bool { pp := strings.Split(p, ".") sName := pp[0] pName := pp[1] return func(cursor *astutil.Cursor) bool { n := cursor.Node() if x, ok := n.(*ast.TypeSpec); ok { return x.Name.Name == sName } else if x, ok := n.(*ast.Field); ok { for _, v := range x.Names { if v.Name == pName { x.Tag = &ast.BasicLit{ Value: tag, Kind: token.STRING, } } } } else if _, ok := n.(*ast.File); ok { return true } else if _, ok := n.(*ast.GenDecl); ok { return true } else if _, ok := n.(*ast.TypeSpec); ok { return true } else if _, ok := n.(*ast.StructType); ok { return true } else if _, ok := n.(*ast.FieldList); ok { return true } return false }}