go / types。不能在其他软件包中比较两个相同的类型吗?

时间:2018-10-13 06:47:58

标签: go

我写了一些代码以通过“ go / types”获得特殊类型

import (
    "go/ast"
    "go/importer"
    "go/parser"
    "go/token"
    "go/types"
    "log"
)    

const (
    Src = `
package types

import (
    "io"
    "net/http"
)

var (
    IOReader    io.Reader
    Err         error
    StatusCode  int
    Request     *http.Request
    Response    *http.Response
)
`
)

const (
    TypeIOReader   = "IOReader"
    TypeErr        = "Err"
    TypeStatusCode = "StatusCode"
    TypeRequest    = "Request"
    TypeResponse   = "Response"
)


func GetType(name string) types.Type {
    fset := token.NewFileSet()
    file, err := parser.ParseFile(fset, "types.go", Src, 0)
    if err != nil {
        log.Fatal(err)
    }

    conf := types.Config{Importer: importer.Default()}
    pkg, err := conf.Check("impler/types", fset, []*ast.File{file}, nil)
    return pkg.Scope().Lookup(name).Type()
}

函数GetType(name string) types.Type可以实现。

当我比较两种类型时,我得到一些奇怪的结果

log.Println(types.Identical(GetType(TypeResponse), GetType(TypeResponse)))
log.Println(types.Identical(GetType(TypeIOReader), GetType(TypeIOReader)))
log.Println(types.Identical(GetType(TypeStatusCode), GetType(TypeStatusCode)))
log.Println(types.Identical(GetType(TypeErr), GetType(TypeErr)))

结果是

false
false
true
true

似乎types.Identical无法比较其他软件包中的两种相同类型? 我如何比较它们?

types.TypeString(typ1, nil) == types.TypeString(typ2, nil)是否足够健壮?

2 个答案:

答案 0 :(得分:0)

即使名称具有相同的结构,Go中具有不同名称的类型也会被视为不同。以下是有关golang类型规则的更多信息:https://golang.org/ref/spec#Type_identity

如果要比较它们,可以将一个值转换为另一种类型:

     type A {...} // some declaration

     type B {...} // the same declaration 

     if a == A(b) {...}

答案 1 :(得分:0)

问题是您每次都要重新解析源,创建一个types.Package及其关联的types.Scope的新实例,从而导致以命名类型出现来自不同的声明(link)。

您获得了int的{​​{1}}和error之类的建筑物类型是基本类型,通过比较(link)被区别对待。我相信,无论您重新解析truelink)多少次,它们都在“ Universe”范围内声明。

要解决您的问题,您必须解析一次源,然后共享结果Src

*types.Package