我正在尝试静态分析Go文件。为此,我需要解析以下格式的变量:
$ sudo rm /usr/local/bin/docker-credential-osxkeychain
我需要找到所有使用点符号访问的变量。例如,我需要知道shape变量具有color属性。并且还需要该颜色变量具有红色属性。 我试图使用go / ast和go / parser程序包,但找不到解决方法。
如果它是诸如shape.color()之类的方法,那么就不应该将其计算在内
答案 0 :(得分:1)
您似乎正在尝试创建自己的AST,因为您提供的表达式的右侧似乎不是变量,否则我将其假定为结构。但是,这也没有意义,因为将名为red
的字段放在名为color
的结构中实际上是不合逻辑的。似乎您正在尝试访问包中的变量,但这也不起作用,因为首字母小写表示该实体未导出。
抛开所有这些,我写了一些代码片段来遵守您列出的条件。
https://play.golang.org/p/gIpctQ1XSgT,我仅将其改编成一行,并在不满足简短条件时惊慌失措。随时根据需要进行调整。
package main
import (
"go/ast"
"go/format"
"go/parser"
"go/token"
"os"
)
func main() {
expr, err := parser.ParseExpr("shape.color==color.red")
if err != nil {
panic(err)
}
// Checking if the expression was binary.
bExpr, ok := expr.(*ast.BinaryExpr)
if !ok {
panic("expr is not a binary expr.")
}
// If the operation is not “==”, die.
if bExpr.Op != token.EQL {
panic("the op should have been ==.")
}
// Left must be a selector expr, meaning followed with a selector which is “dot” in this case.
left, ok := bExpr.X.(*ast.SelectorExpr)
if !ok {
panic("left should have been a selector expr.")
}
// Same as above.
right, ok := bExpr.Y.(*ast.SelectorExpr)
if !ok {
panic("right should have been a selector expr.")
}
// Checking for attributes.
if left.Sel.Name != "color" {
panic("left should have had a color attr.")
}
// Same as above.
if right.Sel.Name != "red" {
panic("right should have had a red attr.")
}
// Then we finally gofmt the code and print it to stdout.
if err := format.Node(os.Stdout, token.NewFileSet(), expr); err != nil {
panic(err)
}
}
答案 1 :(得分:1)
啊!以下代码显示所有使用点符号访问的变量!
// No modifiable code
namespace my
{
template<class T> void swap(T a, T b) { /*.. */ }
struct Obj { /*..*/ };
}
// Your code:
namespace my
{
void swap(Obj& lhs, Obj& rhs)
{
// my::swap<Obj&>(lhs, rhs);
std::swap(lhs, rhs);
}
}
// In namespace you want.
void doSortStuff()
{
std::vector<my::Obj> arr;
std::sort(arr.begin(), arr.end());
}
答案 2 :(得分:0)
如果要比较两个事先不知道的go变量,则需要使用反射。这将使您能够反思地比较两个字段:
type color struct {
Red string
}
type shape struct {
Color string
}
func main() {
color := color{Red: "red"}
shape := shape{Color: "red"}
colorVal := reflect.ValueOf(color)
shapeVal := reflect.ValueOf(shape)
colorRedField := colorVal.FieldByName("Red")
shapeColorField := shapeVal.FieldByName("Color")
fmt.Println(colorRedField)
fmt.Println(shapeColorField)
fmt.Println(colorRedField.Interface() == shapeColorField.Interface())
}