Golang程序转换实践指南
Golang程序转换实践指南 我正在使用Go进行基于AST的转换。我试图添加一个额外的导入包“manipulate”,并将其设置到现有的导入中。使得输入和输出看起来如下所示:
输入程序 package main import ( . “a” ) **** 输出程序 **** package main import ( . “a” . “manipulate” )
在下面的代码中,我得到了错误的输出,如下所示: package main import ( . “a” ) import ( “manipulate” )
关于如何解决上述问题,有什么帮助吗?
以下是代码片段:
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"log"
"os"
)
func exercises1(filename string) {
// Create the AST by parsing the source code.
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
bascilit := &ast.BasicLit{Kind: token.STRING, Value: "\"manipulate\""}
identdot := ast.NewIdent(" ")
importspec := &ast.ImportSpec{Name: identdot, Path: bascilit}
import0 := &ast.GenDecl{Specs: []ast.Spec{importspec}, Tok: token.IMPORT, Lparen: 3}
for _, f := range node.Decls {
_, ok := f.(*ast.GenDecl)
if ok {
list := append(node.Decls, import0)
node.Decls = list
}
}
}
func main() {
exercises1("exercise1.go")
}
更多关于Golang程序转换实践指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang程序转换实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题出在您将新的导入声明直接追加到 node.Decls 中,这会导致出现多个 import 块。正确的做法是找到现有的导入声明,并将新的导入规约添加到其 Specs 列表中。以下是修改后的代码:
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"log"
"os"
)
func exercises1(filename string) {
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
if err != nil {
log.Fatal(err)
}
// 创建新的导入规约
newImport := &ast.ImportSpec{
Name: ast.NewIdent("."), // 点导入
Path: &ast.BasicLit{
Kind: token.STRING,
Value: `"manipulate"`,
},
}
// 查找现有的导入声明
for _, decl := range node.Decls {
if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
// 将新导入添加到现有导入声明的 Specs 中
genDecl.Specs = append(genDecl.Specs, newImport)
break
}
}
// 输出修改后的 AST
if err := printer.Fprint(os.Stdout, fset, node); err != nil {
log.Fatal(err)
}
}
func main() {
exercises1("exercise1.go")
}
这段代码会正确地将 ". \"manipulate\"" 添加到现有的导入声明中,输出结果如下:
package main
import (
. "a"
. "manipulate"
)
关键修改点:
- 使用
ast.NewIdent(".")创建点导入标识符 - 通过遍历
node.Decls找到现有的token.IMPORT声明 - 将新导入规约追加到现有导入声明的
Specs切片中 - 移除了不必要的
Lparen设置(AST 会自动处理括号)

