装饰的语法树 - 以完美的保真度操作 Go 代码。
dst 包支持以高保真度操作 Go 语法树。装饰(例如注释和行间距)在修改树时仍然附着在正确的节点上。 go/ast 包的缺陷在哪里? go/ast 包并非为源代码操作而创建的。注释以字节偏移存储,而不是附着在节点上,因此重新排列节点会破坏输出。有关更多信息,请参阅 此 Go 问题。 考虑以下示例,我们希望将两个语句的顺序反转。如您所见,注释并未附着在正确的节点上: ```gocode := `package a
func main(){ var a int // foo var b string // bar } ` fset := token.NewFileSet() f, err := parser.ParseFile(fset, "", code, parser.ParseComments) if err != nil { panic(err) }
list := f.Decls[0].(*ast.FuncDecl).Body.List list[0], list[1] = list[1], list[0]
if err := format.Node(os.Stdout, fset, f); err != nil { panic(err) }
//Output:
//package a
//
//func main() {
// // foo
// var b string
// var a int
// // bar
//}
``` 以下是使用 dst 的相同示例:
code := `package a
func main(){
var a int // foo
var b string // bar
}
`
f, err := decorator.Parse(code)
if err != nil {
panic(err)
}
list := f.Decls[0].(*dst.FuncDecl).Body.List
list[0], list[1] = list[1], list[0]
if err := decorator.Print(f); err != nil {
panic(err)
}
//Output:
//package a
//
//func main() {
// var b string // bar
// var a int // foo
//}
``` 使用 [decorator](https://godoc.org/github.com/dave/dst/decorator) 包中的几个 `Parse` 和 `Print` 便利函数,可以解析源文件到 `dst`,并在修改后打印结果。 如果需要更精细的控制,可以使用 [Decorator](https://godoc.org/github.com/dave/dst/decorator#Decorator) 将 `ast` 转换为 `dst`,以及 [Restorer](https://godoc.org/github.com/dave/dst/decorator#Restorer) 将其再次转换回去。暂无开放 Issues,或尚未同步最近议题。