【问题标题】:Check if ast.Expr Implements Interface in Go检查 ast.Expr 是否在 Go 中实现接口
【发布时间】:2021-12-01 07:45:24
【问题描述】:

有什么方法可以检查ast.Expr 是否像fmt.Stringer 一样实现interface

我发现这个函数types.Implements() 可以在这里使用,但是我不确定如何从现有的interface 类型中创建types.Interface,例如fmt.Stringer,这是types.Implements() 函数所必需的。

我正在寻找这样的函数实现:

func isStringer(ti *types.Info, obj ast.Expr) bool {
    panic("not implemented")
}

我目前使用的解决方法:

func isStringer(ti *types.Info, obj ast.Expr) bool {
    t := ti.TypeOf(obj).(*types.Named)

    for i := 0; i < t.NumMethods(); i++ {
        if t.Method(i).Type().(*types.Signature).String() == "func() string" {
            return true
        }
    }

    return false
}

【问题讨论】:

  • 这个例子使用reflect包,我想从与reflect不兼容的types包中得到同样的结果。

标签: go interface abstract-syntax-tree analyzer


【解决方案1】:

我检查接口是否实现的常用方法是使用长格式type assertion

例如:

func isStringer(obj ast.Expr) bool {
    _, ok := obj.(fmt.Stringer)
    return ok
}

这里发生的事情是,当我们为类型断言提供第二个变量时(通常按约定命名为ok),如果无法强制转换类型,go 不会恐慌,而是设置ok = false

然后我们可以简单地返回ok 的值,并确保如果ok == true 实现了stringer,obj 实现了stringer,如果ok == false 没有实现。

如果我们想使用 stringer 接口提供的方法,我们也可以返回 cast 变量:

func isStringer(obj ast.Expr) (fmt.Stringer, bool) {
    return obj.(fmt.Stringer)
}

【讨论】:

    猜你喜欢
    • 2016-04-02
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 2018-10-19
    • 2010-09-21
    • 2012-03-06
    • 2015-03-04
    相关资源
    最近更新 更多