ast.Inspect 不走 *ast.UnaryExpr
来源:stackoverflow
时间:2024-04-22 16:30:33 296浏览 收藏
哈喽!大家好,很高兴又见面了,我是golang学习网的一名作者,今天由我给大家带来一篇《ast.Inspect 不走 *ast.UnaryExpr》,本文主要会讲到等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看看吧!
问题内容
我正在尝试检查 go 源代码以制作一个工具。为此,我使用 ast.inspect 函数。
我需要知道函数/方法内部如何使用通道。
我将此作为要检查的示例代码:
package main
func b(ch chan int) {
for x := range ch {
}
}
这是函数 b 的 ast:
0 *ast.funcdecl {
1 . name: *ast.ident {
2 . . namepos: -:4:6
3 . . name: "b"
4 . . obj: *ast.object {
5 . . . kind: func
6 . . . name: "b"
7 . . . decl: *(obj @ 0)
8 . . }
9 . }
10 . type: *ast.functype {
11 . . func: -:4:1
12 . . params: *ast.fieldlist {
13 . . . opening: -:4:7
14 . . . list: []*ast.field (len = 1) {
15 . . . . 0: *ast.field {
16 . . . . . names: []*ast.ident (len = 1) {
17 . . . . . . 0: *ast.ident {
18 . . . . . . . namepos: -:4:8
19 . . . . . . . name: "ch"
20 . . . . . . . obj: *ast.object {
21 . . . . . . . . kind: var
22 . . . . . . . . name: "ch"
23 . . . . . . . . decl: *(obj @ 15)
24 . . . . . . . }
25 . . . . . . }
26 . . . . . }
27 . . . . . type: *ast.chantype {
28 . . . . . . begin: -:4:11
29 . . . . . . arrow: -
30 . . . . . . dir: 3
31 . . . . . . value: *ast.ident {
32 . . . . . . . namepos: -:4:16
33 . . . . . . . name: "int"
34 . . . . . . }
35 . . . . . }
36 . . . . }
37 . . . }
38 . . . closing: -:4:19
39 . . }
40 . }
41 . body: *ast.blockstmt {
42 . . lbrace: -:4:21
43 . . list: []ast.stmt (len = 1) {
44 . . . 0: *ast.rangestmt {
45 . . . . for: -:5:2
46 . . . . key: *ast.ident {
47 . . . . . namepos: -:5:6
48 . . . . . name: "x"
49 . . . . . obj: *ast.object {
50 . . . . . . kind: var
51 . . . . . . name: "x"
52 . . . . . . decl: *ast.assignstmt {
53 . . . . . . . lhs: []ast.expr (len = 1) {
54 . . . . . . . . 0: *(obj @ 46)
55 . . . . . . . }
56 . . . . . . . tokpos: -:5:8
57 . . . . . . . tok: :=
58 . . . . . . . rhs: []ast.expr (len = 1) {
59 . . . . . . . . 0: *ast.unaryexpr {
60 . . . . . . . . . oppos: -:5:11
61 . . . . . . . . . op: range
62 . . . . . . . . . x: *ast.ident {
63 . . . . . . . . . . namepos: -:5:17
64 . . . . . . . . . . name: "ch"
65 . . . . . . . . . . obj: *(obj @ 20)
66 . . . . . . . . . }
67 . . . . . . . . }
68 . . . . . . . }
69 . . . . . . }
70 . . . . . }
71 . . . . }
72 . . . . tokpos: -:5:8
73 . . . . tok: :=
74 . . . . x: *(obj @ 62)
75 . . . . body: *ast.blockstmt {
76 . . . . . lbrace: -:5:20
77 . . . . . rbrace: -:7:2
78 . . . . }
79 . . . }
80 . . }
81 . . rbrace: -:8:1
82 .
正如您在 59 行中看到的,我们可以看到有一个 unaryexpr 节点,其中 op 设置为 range。这就是我想要捕获的节点。
我尝试使用此代码遍历 ast 并且仅捕获该节点。
exampleFunc := `
package main
func B(ch chan int) {
for x := range ch {
}
}
`
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "-", exampleFunc, parser.ParseComments)
ast.Inspect(file, func(node ast.Node) bool {
fn, ok := node.(*ast.UnaryExpr) // try to cast
if !ok {
return true
}
ast.Print(fset, fn)
return true
})
但似乎不起作用。
知道为什么,打印整个 funcdecl 的 ast,我可以看到有一个 unaryexpr 节点,但在尝试获取该节点时什么也没有出现?
解决方案
作为@mkopriva,*ast.Ident 节点被视为叶子。因此,我们需要手动从 RangeStmt 移动到 AssignStmt (如果有的话),然后再次使用检查来到达 UnaryExpr
理论要掌握,实操不能落!以上关于《ast.Inspect 不走 *ast.UnaryExpr》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
最新阅读
更多>
-
139 收藏
-
204 收藏
-
325 收藏
-
478 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习