脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - Golang干货分享之利用AST实现AOP功能

Golang干货分享之利用AST实现AOP功能

2023-04-12 15:02落风雪 Golang

本文主要是一个纯干货分享,主要介绍了Golang如何利用AST实现AOP功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下

简述

本文全是简单的干货,直接让我们知道如何实现一个AOP功能。在这个示例中,我们定义了一个名为 MyStruct 的结构体,它有两个字段和两个方法。然后,我们使用 Golang 的 AST 包来遍历源代码的 AST,并找到名为 MyStruct 的结构体的方法。

对于每个方法,我们创建一个新的日志语句,并将其插入到方法体的开头。这样,在调用该方法时,就会自动打印出一条日志信息。

最后,我们使用 Golang 的 printer.Fprint 函数将新生成的 AST 节点输出为 Go 代码。

希望这个示例能够帮助您了解如何使用 Golang 的 AST 包来实现 AOP。

示例代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main
 
import (
    "go/ast"
    "go/parser"
    "go/printer"
    "go/token"
    "log"
    "os"
)
 
func main() {
    src := `package main
 
type MyStruct struct {
    Field1 int
    Field2 string
}
 
func (m *MyStruct) Method1() {
    println(m.Field1)
}
 
func (m *MyStruct) Method2() {
    println(m.Field2)
}
`
    fset := token.NewFileSet()
    f, err := parser.ParseFile(fset, "", src, 0)
    if err != nil {
        log.Fatal(err)
    }
 
    ast.Inspect(f, func(n ast.Node) bool {
        switch x := n.(type) {
        case *ast.FuncDecl:
            if x.Recv != nil && len(x.Recv.List) == 1 && x.Recv.List[0].Names[0].Name == "m" && x.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).Name == "MyStruct" {
 
                logStmt := &ast.ExprStmt{
                    X: &ast.CallExpr{
                        Fun: &ast.SelectorExpr{
                            X:   ast.NewIdent("log"),
                            Sel: ast.NewIdent("Println"),
                        },
                        Args: []ast.Expr{&ast.BasicLit{
                            ValuePos: x.Pos(),
                            Kind:     token.STRING,
                            Value:    "\"Entering " + x.Name.Name + "\"",
                        }},
                    },
                }
 
                x.Body.List = append([]ast.Stmt{logStmt}, x.Body.List...)
                return false
            }
 
        }
        return true
    })
 
    printer.Fprint(os.Stdout, fset, f)
}
 
 
//----------------输出
package main
 
type MyStruct struct {
    Field1  int
    Field2  string
}
 
func (m *MyStruct) Method1() {
    log.Println("Entering Method1")
    println(m.Field1)
}
 
func (m *MyStruct) Method2() {
    log.Println("Entering Method2")
    println(m.Field2)
}

到此这篇关于Golang干货分享之利用AST实现AOP功能的文章就介绍到这了,更多相关Golang AST实现AOP内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/7211401380770234427

延伸 · 阅读

精彩推荐
  • Golang如何在VScode 中编译多个Go文件

    如何在VScode 中编译多个Go文件

    这篇文章主要介绍了VScode 中编译多个Go文件的实现方法,本文通过实例图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下...

    叨陪鲤56962021-09-17
  • Golanggo run main.go 一直提示找不到包的解决方案

    go run main.go 一直提示找不到包的解决方案

    这篇文章主要介绍了go run main.go 一直提示找不到包的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    柴米yo7772021-06-10
  • Golanggolang高并发限流操作 ping / telnet

    golang高并发限流操作 ping / telnet

    这篇文章主要介绍了golang高并发限流操作 ping / telnet,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    出逃的迪斯尼猫咪4842021-03-13
  • GolangGo语言基础数组用法及示例详解

    Go语言基础数组用法及示例详解

    这篇文章主要为大家介绍了Go语言基础Go语言数组的用法及示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    枫少文5532021-12-07
  • GolangGo语言JSON解析器gjson使用方法详解

    Go语言JSON解析器gjson使用方法详解

    这篇文章主要介绍了Go语言json解析框架与gjson,JSON 解析是我们不可避免的常见问题,在Go语言中,我们可以借助gjson库来方便的进行json属性的提取与解析,...

    go2coding3312022-12-07
  • Golang用golang如何替换某个文件中的字符串

    用golang如何替换某个文件中的字符串

    这篇文章主要介绍了用golang实现替换某个文件中的字符串操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    hackssssss11702021-05-30
  • Golang详解Go语言中的作用域和变量隐藏

    详解Go语言中的作用域和变量隐藏

    这篇文章主要为大家介绍了Go语言中的作用域和变量隐藏,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,感兴趣的小伙伴可以了解一下...

    宇宙之一粟4062022-09-29
  • Golang剖析Go编写的Socket服务器模块解耦及基础模块的设计

    剖析Go编写的Socket服务器模块解耦及基础模块的设计

    这篇文章主要介绍了Go的Socket服务器模块解耦及日志和定时任务的模块设计,举了一些Go语言编写的服务器模块的例子,需要的朋友可以参考下 ...

    G1SLu5632020-04-29