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"
)

关键修改点:

  1. 使用 ast.NewIdent(".") 创建点导入标识符
  2. 通过遍历 node.Decls 找到现有的 token.IMPORT 声明
  3. 将新导入规约追加到现有导入声明的 Specs 切片中
  4. 移除了不必要的 Lparen 设置(AST 会自动处理括号)
回到顶部